Der Titel dieser Ausgabe mag seltsam erscheinen, weil ich nicht genau herausfinden kann, was das Problem ist. Aber hier ist, was passiert:
pragma solidity ^0.4.13;
contract Escrow {
address public owner;
uint public fee;
//Balances temporarily made public for testing; to be removed
mapping (address => mapping (address => uint)) public balances;
function Escrow() public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
//Fee should be set in PPM
function setFee(uint price) onlyOwner external {
fee = price;
}
function start(address payee) payable external {
balances[msg.sender][payee] = balances[msg.sender][payee] + msg.value;
}
function end(address payer, address payee) onlyOwner external {
uint value = balances[payer][payee];
//uint paidFee = value / (1000000 / fee);
//uint payment = value - paidFee;
//payee.transfer(payment);
//owner.transfer(paidFee);
//balances[payer][payee] = 0
payee.transfer(value)
}
}
Ich habe eine Reihe von Zeilen auskommentiert, die ich gerne in der end
Funktion zum Laufen bringen würde, weil ich nicht einmal die anderen Teile zum Laufen bringen kann.
Schritte:
Vertrag von erster Adresse in testRPC erstellen
Ich rufe start von der zweiten Adresse in meinem testRPC an und sende 2 ETH an die letzte Adresse:start("0xb631fc401038e191fa38c4ff20dcce8d13eb6ebc" , { from "0x1c34d277b51ec49536fe7843e289933e0f8020ed", value: 2000000000000000000000 })
Ich überprüfe: balances("0x1c34d277b51ec49536fe7843e289933e0f8020ed", "0xb631fc401038e191fa38c4ff20dcce8d13eb6ebc")
, ich sehe 0: uint256: 2000000000000000000
--So weit, so gut.
Hier komme ich in Schwierigkeiten. Wenn ich anrufe end("0x1c34d277b51ec49536fe7843e289933e0f8020ed", "0xb631fc401038e191fa38c4ff20dcce8d13eb6ebc")
, bekomme ich:transact to Escrow.end errored: VM Exception while processing transaction: out of gas
Wenn ich end
zu just return ändere balances[payer][payee]
, bekomme ich 0.
Wenn ich ändere end
, um nur 1 ETH an den Zahlungsempfänger zu überweisen, erhalte ich einen Gasfehler.
Ich kann also nicht herausfinden, was die Ursache dieses Problems ist. Können Sie einen Rat geben?
end() Methode dieses Vertrages sollte zahlbar sein, da innerhalb der Methode eine Übertragung stattfindet. Und verwenden Sie auch safeMath.sol von OpenZeppelin für alle mathematischen Berechnungen innerhalb des Vertrags. Ich schreibe den Code um. Finden Sie bitte:
safeMath.sol
pragma solidity ^0.4.21;
/**
* @author OpenZeppelin
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
escrow.sol
pragma solidity ^0.4.21;
import './safeMath.sol';
contract Escrow {
using SafeMath for uint;
address public owner;
uint public fee;
mapping (address => mapping (address => uint)) public balances;
function Escrow() public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
//Fee should be set in PPM
function setFee(uint price) onlyOwner external {
fee = price;
}
function start(address payee) payable external {
balances[msg.sender][payee] = balances[msg.sender][payee] + msg.value;
}
function end(address payer, address payee) onlyOwner payable external {
uint value = balances[payer][payee];
uint paidFee = value.div(uint(1000000).div(fee));
uint payment = value.sub(paidFee);
payee.transfer(payment);
owner.transfer(paidFee);
balances[payer][payee] = 0;
payee.transfer(value);
}
}
Ich denke, Sie müssen das Von-Konto in Schritt 4 hinzufügen, wie Sie es in Schritt 2 getan haben, aber ohne Wert. Andernfalls weiß es nicht, welches Konto für Benzin belastet werden soll.
Aus deinem Code
function start(address payee) payable external {
balances[msg.sender][payee] = balances[msg.sender][payee] + msg.value;
}
Um diese Funktion aufzurufen,
start("0xb631fc401038e191fa38c4ff20dcce8d13eb6ebc" , { from "0x1c34d277b51ec49536fe7843e289933e0f8020ed", value: 2000000000000000000000 })
Sie haben Wert übergeben und jetzt wird Ihr Wert nach dem Hinzufügen endgültig value
gespeichert . Springen wir zur zweiten Funktionbalances[msg.sender][payee]
function end(address payer, address payee) onlyOwner external {
uint value = balances[payer][payee];
payee.transfer(value);
}
Wenn Sie diese Funktion zum ersten Mal ausführen, wird Ihr gesamter Wert an eine Adresse des Zahlungsempfängers übertragen.
Wenn Sie diese Funktion zum zweiten Mal ausführen, haben Sie keinen Wert mehr, dann erhalten Sie den vm-Fehler.
Wenn Sie diesen Fehler nicht gemacht haben, überprüfen Sie web3js. Bitte übergeben Sie optionale Parameter.
end("0x1c34d277b51ec49536fe7843e289933e0f8020ed", "0xb631fc401038e191fa38c4ff20dcce8d13eb6ebc", {from,gasPrice,gas})
options - Object (optional): The options used for calling.
from - String (optional): The address the call “transaction” should be made from.
gasPrice - String (optional): The gas price in wei to use for this call “transaction”.
gas - Number (optional): The maximum gas provided for this call “transaction” (gas limit).
Rob Hitchens
pragma ^0.4.13
und Ihrem Prozess. Ich vermute, Sie haben Versionsinkompatibilitäten zu klären. Ein Vorschlag ist, die Beschwerden zu beseitigen^
und die daraus resultierenden Beschwerden zu lösen, indem die Dinge in eine starke explizite Ausrichtung gebracht werden. Ich hoffe es hilft.