Невозможно внести свой вклад в краудсейл-контракт

У меня есть следующие два контракта:

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; 
    }
}

Я пытаюсь выполнить функцию вклада, но в amountRaised не происходит никаких изменений, и передача функции также не вызывается. Что я делаю неправильно?

Я развернул первый токен-контракт. затем использовал его адрес в качестве параметра для вызова конструктора. я использую 2 узла: первый узел развертывает контракты, а второй вызывает функцию вклада следующим образом: fundingGoal равен 10000 (скажем)

var camp = eth.contract(abi).at(address)
camp.contribute.sendTransaction({from : eth.coinbase , value : 5000})
Можете ли вы предоставить некоторые подробности о том , как вы звоните?
я обновил вопрос
Вы можете показать выходы eth.getTransactionи eth.getTransactionReceiptна этом tx?
Я пытаюсь сделать то же самое, но получил много неудачных транзакций. Каким должен быть адрес токена? Это адрес контракта или адрес держателя токена? Если адрес держателя токена, должен ли он быть создателем контракта токена? Спасибо.

Ответы (1)

Резюме

В вашей транзакции закончился газ, так как вы использовали количество газа по умолчанию. Установите более высокое количество газа, и транзакция должна пройти успешно.



Подробности

Газ по умолчанию для транзакции с контрактом составляет 90 000. Газ по умолчанию для транзакции с другими учетными записями составляет 21 000.

Когда я отправил транзакцию, используя газ по умолчанию 90 000, либо пропустив поле газа, либо указав газ: 90000, транзакция исчерпала газ ( gasUsedуказанный газ ==):

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
}

Когда я увеличил указанный газ в 100 000, у транзакции закончился газ:

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
}

Когда я увеличил указанный газ до 1 000 000, транзакция прошла успешно:

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
}

Проверяем успешность транзакции:

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

Странно то, что требуемый газ был 87765, но 90 000 по умолчанию или указанные 100 000 не помогли.

Итак, я попробовал газ 120 000:

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

А пробовал газ 100000 и теперь работает:

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

Я думаю, что причина неудачи первоначальных транзакций заключается в том, что стоимость создания первого сопоставления больше, чем стоимость изменения значения в сопоставлении.

Итак, я протестировал простой контракт и подтвердил, что создание записи сопоставления стоит больше газа, чем обновление значения существующей записи сопоставления:

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

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

Первый вызов транзакции test(...)дал следующий результат:

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. 

А второй транзакционный вызов той же функции с тем же адресным параметром дал следующий результат:

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. 

Третий транзакционный вызов той же функции с другим параметром адреса дал следующий результат:

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.