address.transfer (значение) выбрасывает ошибку в договоре солидности.

Я строю контракт одобрения в Remix и застрял в этом вопросе.

Когда я пытаюсь передать Вэй, используя address.transfer(value) , он выдает ошибку. Я отметил это в коде ниже.

Возможно, ошибка связана со struct Request объявленной в конструкторе, потому что отладчик ремиксов заканчивается там, когда .transfer() не удается, хотя я не смог найти объяснения.

 pragma solidity ^0.4.17; contract Campaign { struct Request { string description; uint32 value; address recipient; bool complete; uint approvalCount; mapping(address => bool) approvals; } Request[] public requests; address public manager; uint32 public minimumContribution; // tutorial uses 'approvers' not 'contributors' mapping(address => bool) public contributors; uint32 public contributorCount; modifier restricted { require(msg.sender == manager ); _; } constructor(uint32 minimum) public { manager = msg.sender; minimumContribution = minimum; } function contribute() public payable{ require(msg.value > minimumContribution); contributors[msg.sender] = true; // because contributor is contributorCount++; } function createRequest(string description, uint32 value, address recipient) public restricted { Request memory newRequest = Request({ description: description, value: value, recipient: recipient, complete: false, approvalCount: 0 }); requests.push(newRequest); } function approveRequest(uint16 index) public { Request storage r = requests[index]; // make sure the address has contributed, but has not approved this one yet require(contributors[msg.sender]); require(!r.approvals[msg.sender]); r.approvals[msg.sender] = true; r.approvalCount++; } function finalizeRequest(uint16 index) public restricted { Request storage r = requests[index]; // make sure more than 50% of contributors approved this request require(r.approvalCount > (contributorCount / 2)); //make sure that this request has not been completed before require(!r.complete); // FAILS ON THIS LINE. Remix debugger goes through this line then ends on line 3 of the contract, in the constructor function. r.recipient.transfer(r.value); // mark this request as completed r.complete = true; } } 

Обратите внимание, что после сбоя функции .transfer() отладчик переходит к функции конструктора, где создается struct Request {...} . (в этом ли проблема?)

Я подумал, что это может быть .transfer() функция .transfer() , поэтому я попытался изолировать передачу, вызвав ее в отдельной функции, но она все равно не сработала.

Не уверен, поможет ли это, но address.transfer() адрес (адрес в address.transfer() ) скопирован с одного из резервных адресов, которые remix создает в javascriptVM.

Если вы закомментируете строку r.recipient.transfer(r.value) , будет ли функция успешной? Если это так, я думаю, что r.value больше, чем остаток контракта.
Возможно, попробуйте r.recipient.transfer(address(this).balance); чтобы подтвердить.
Вы правы @smarx. Проходит при использовании address(this).balance .
Я добавлю еще один require(); обеспечение того, чтобы это значение было меньше, чем остаток по контракту.

Ответы (1)

Количество wei, указанное в r.value, было больше, чем указано в договоре. Я добавил строку в свой контракт, чтобы убедиться, что контракт содержит достаточно денег:

require(address(this).balance > r.value);