Beitrag zum Crowdsale-Vertrag nicht möglich

Ich habe folgende zwei Verträge:

contract Token {
   string public name;
   uint8 public decimals;
   address public owner;
   mapping (address => uint256) public balanceOf;

    function Token(uint256 initialSupply, string tokenName, uint8 decimalUnits)    {
        balanceOf[msg.sender] = initialSupply;             
        name = tokenName;                                  
        decimals = decimalUnits;  
        owner = msg.sender;
    }

    function transfer(address _to, uint256 _value) {
        balanceOf[owner] -= _value;
        balanceOf[_to] += _value;
    }
}

contract Crowdsale {

    address public beneficiary;
    uint public fundingGoal;
    uint public amountRaised; 
    uint public deadline;
    uint public price;   
    Token public tokenReward;
    mapping(address => uint256) public balanceOf; 
    bool public fundingGoalReached = false; 
    bool public crowdsaleClosed = false;

    function Crowdsale(uint _fundingGoal, uint _duration, uint costToken, Token addressOfToken) { 
        beneficiary = msg.sender; 
        fundingGoal = _fundingGoal; 
        deadline = now + _duration ; 
        price = costToken;
        tokenReward = Token(addressOfToken); 
    }

    function contribute() public {
        if (crowdsaleClosed) throw; 
        uint amount = msg.value; 
        balanceOf[msg.sender] = amount; 
        amountRaised += amount; 
        tokenReward.transfer(msg.sender, amount / price); 
    }

    modifier afterDeadline() {
        if (now >= deadline) 
            _ 
    }

    function checkGoalReached() afterDeadline{
        if (amountRaised >= fundingGoal) { 
           fundingGoalReached = true; 
        } 
        crowdsaleClosed = true; 
    }
}

Ich versuche, die Contribut-Funktion auszuführen, aber es tritt keine Änderung an der Menge ein und die Funktion Transfer wird auch nicht aufgerufen. Was mache ich falsch?

Ich habe den ersten Token-Vertrag bereitgestellt. verwendet dann seine Adresse als Parameter für den Konstruktoraufruf. Ich verwende 2 Knoten, der erste Knoten stellt die Verträge bereit und der zweite ruft die Beitragsfunktion wie folgt auf: fundingGoal ist 10000 (sagen wir)

var camp = eth.contract(abi).at(address)
camp.contribute.sendTransaction({from : eth.coinbase , value : 5000})
Können Sie einige Details dazu angeben, wie Sie den Anruf tätigen?
Ich habe die Frage aktualisiert
Können Sie die Ausgaben von eth.getTransactionund eth.getTransactionReceiptauf diesem TX zeigen?
Ich versuche dasselbe zu tun, habe aber viele fehlgeschlagene Transaktionen erhalten. Wie soll die Adresse des Tokens lauten? Ist es die Vertragsadresse oder die Adresse des Token-Inhabers? Wenn die Adresse des Token-Inhabers der Ersteller des Token-Vertrags sein sollte? Vielen Dank.

Antworten (1)

Zusammenfassung

Bei Ihrer Transaktion ist das Gas ausgegangen, da Sie die Standard-Gasmenge verwendet haben. Stellen Sie eine höhere Gasmenge ein und die Transaktion sollte erfolgreich sein.



Einzelheiten

Das Standardgas für eine Transaktion zu einem Vertrag beträgt 90.000. Das Standardgas für eine Transaktion auf andere Konten ist 21.000.

Als ich die Transaktion mit dem Standardgas von 90.000 gesendet habe, indem ich entweder das Gasfeld weggelassen oder Gas angegeben habe: 90000, ging der Transaktion das Gas aus ( gasUsed== Gas angegeben):

var tx = crowdsale1.contribute.sendTransaction({
    from : eth.accounts[1], 
    value : 5000, 
    gas:90000});
"0x3470d1f3d8f30ca9a8dcd6bc462c39048dd534fdb3a7ccec20c142cb5c841315"
eth.getTransactionReceipt(tx)
{
  blockHash: "0x810850aa7cc73cc88f782c845fde37ff755610e72e0bd6ba2f174ffc1e257133",
  blockNumber: 5012,
  contractAddress: null,
  cumulativeGasUsed: 90000,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 90000,
  logs: [],
  root: "0bde4bb628081d72749ce52c1a2c113095d58ce24616f9954b054a0b74af737b",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0x3470d1f3d8f30ca9a8dcd6bc462c39048dd534fdb3a7ccec20c142cb5c841315",
  transactionIndex: 0
}

Als ich das angegebene Gas von 100.000 erreichte, ging der Transaktion das Gas aus:

var tx = crowdsale1.contribute.sendTransaction({
    from : eth.accounts[1], 
    value : 5000, 
    gas: 100000})
"0x8923eeaae8b8b4bbc1b4d5ef2f818b6111faabcfea7141c075334222acc51fbf"
eth.getTransactionReceipt(tx)
{
  blockHash: "0x700e07a23ca603d0dc4d76ff53f3f8419eab9453ea69b341d970b0c94444d2de",
  blockNumber: 5018,
  contractAddress: null,
  cumulativeGasUsed: 100000,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 100000,
  logs: [],
  root: "29cd898651720f714e8f7ce17e4de6f34836aa8ab394762d00b77f49d8e82ab3",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0x8923eeaae8b8b4bbc1b4d5ef2f818b6111faabcfea7141c075334222acc51fbf",
  transactionIndex: 0
}

Als ich das angegebene Gas von 1.000.000 erreichte, war die Transaktion erfolgreich:

var tx = crowdsale1.contribute.sendTransaction({
    from : eth.accounts[1], 
    value : 5000, 
    gas: 1000000})
"0x42493b8d656889064e21dcac0074c0323d3bff56b0f26a8b724f9437de3bddca"
eth.getTransactionReceipt(tx)
{
  blockHash: "0xd6849c93366f15a61957f48803e41afbab03085c454339dbd43ec311e02c7901",
  blockNumber: 5024,
  contractAddress: null,
  cumulativeGasUsed: 87765,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 87765,
  logs: [],
  root: "ef9eca739275dd9e316caaac26db9635b72b4948a0eeb5e600adeec7020f357f",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0x42493b8d656889064e21dcac0074c0323d3bff56b0f26a8b724f9437de3bddca",
  transactionIndex: 0
}

Überprüfen, ob die Transaktion erfolgreich war:

> crowdsale.balanceOf(eth.accounts[1]);
5000
> token.balanceOf(eth.accounts[1]);
50

Das Seltsame ist, dass das erforderliche Gas 87765 war, aber die Standardeinstellung 90.000 oder die angegebenen 100.000 fehlschlug.

Also habe ich Gas von 120.000 probiert:

> eth.getTransactionReceipt(tx)
{
  blockHash: "0x8da8d92cd2505a4c41c6b5c7f8edb844127f7780faec50393e915fe4c0dfb522",
  blockNumber: 5065,
  contractAddress: null,
  cumulativeGasUsed: 42765,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 42765,
  logs: [],
  root: "2aafe894dfa857a79faa423732a79760328f981d50690159b56fcf8bbdac747a",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0xc2441e38fde80ed853943d0e178a76542391cf8fc8e1b6f146aad3ce90d9bbbb",
  transactionIndex: 0
}

Und ich habe Gas von 100.000 ausprobiert und jetzt funktioniert es:

> eth.getTransactionReceipt(tx)
{
  blockHash: "0x9f4fef406d6fe0c8a77e786f50c952001b7fa933c2ffa5e0b3ca71e1531f066a",
  blockNumber: 5072,
  contractAddress: null,
  cumulativeGasUsed: 42765,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 42765,
  logs: [],
  root: "efaecfe5f23410fed052a30b6b7a0c99e644c519f854965db672f9ad906c3afd",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0x817b30894cff5b94ec9f2011c79a7c447ee6158c7443c4eb1334da7116540825",
  transactionIndex: 0
}

Ich denke, der Grund für das Scheitern der ersten Transaktionen liegt darin, dass die Kosten für die Erstellung der ersten Zuordnung höher sind als die Kosten für die Änderung des Werts in der Zuordnung.

Also habe ich einen einfachen Vertrag getestet und bestätigt, dass die Erstellung des Mapping-Eintrags mehr Benzin kostet als die Aktualisierung des Werts eines bestehenden Mapping-Eintrags:

contract Test {
   mapping (address => uint256) public balanceOf;

   function test(address _address, uint256 _value) {
       balanceOf[_address] = _value;
   }
}

Der erste Transaktionsaufruf test(...)ergab folgendes Ergebnis:

Result: {
  "blockHash": "0x4602ab6c92896a4034ec7a1c73e98f177dd4a6a9585529485e03865210592b28",
  "blockNumber": 5132,
  "contractAddress": null,
  "cumulativeGasUsed": 43147,
  "from": "0xa7857047907d53a2e494d5f311b4b586dc6a96d2",
  "gasUsed": 43147,
  "logs": [],
  "root": "a8e5e666108060eba085b26996c0b2593ee9c3c006f5a48b6133103a3bd00bd4",
  "to": "0x4452da92e2d5828b08a6698f3b828721fe589193",
  "transactionHash": "0xba578464da93ce76b9195450ef7228bb5e0df96eaf92adbd439146da97f960b0",
  "transactionIndex": 0
}
Transaction cost: 43147 gas. 

Und der zweite Transaktionsaufruf derselben Funktion mit demselben Adressparameter ergab das folgende Ergebnis:

Result: {
  "blockHash": "0xefeedd0ed3c61f5f8af40ebc43ad48122a67b8e8178958fc5a7bfc2c03d5ac37",
  "blockNumber": 5134,
  "contractAddress": null,
  "cumulativeGasUsed": 28147,
  "from": "0xa7857047907d53a2e494d5f311b4b586dc6a96d2",
  "gasUsed": 28147,
  "logs": [],
  "root": "21e1c09c2cb2ceff0f5933427ae54eb99db9cbc1a983138cb964c58c50133f17",
  "to": "0x4452da92e2d5828b08a6698f3b828721fe589193",
  "transactionHash": "0x21e86669de32c7ea6bb2a05677e4be6ebc56e4c476e9c2cb5f3ded5aefddb907",
  "transactionIndex": 0
}
Transaction cost: 28147 gas. 

Ein dritter Transaktionsaufruf derselben Funktion mit einem anderen Adressparameter ergab das folgende Ergebnis:

Result: {
  "blockHash": "0xf5d740fffdb5dbd1764591d415307028a98453b9e8040e5dc9e23e0c9d54cd2e",
  "blockNumber": 5144,
  "contractAddress": null,
  "cumulativeGasUsed": 43147,
  "from": "0xa7857047907d53a2e494d5f311b4b586dc6a96d2",
  "gasUsed": 43147,
  "logs": [],
  "root": "fb776d9e8fc7da3d84032de6dab94d33f3c995eccd4b16c4b7ad333fc122f14b",
  "to": "0x4452da92e2d5828b08a6698f3b828721fe589193",
  "transactionHash": "0x7561f93cd5bd335783661dfad12067387c1b7c6fe455b6db2f194ea30a1429e1",
  "transactionIndex": 0
}
Transaction cost: 43147 gas.