Не удается выполнить функции записи в смарт-контракте — неверный адрес?

У меня есть следующий простой смарт-контракт...

contract SimpleStorage {
    uint storedData;
    function set(uint x) {
        storedData = x;
    }
    function get() constant returns (uint retVal) {
        return storedData;
    }
}

Который я развертываю с помощью следующего кода в консоли geth...

var source = "contract SimpleStorage...[code here]"
var compiled = web3.eth.compile.solidity(source)
var contract = web3.eth.contract(compiled.Coin.info.abiDefinition)
var storage = contract.new({from:web3.eth.accounts[0], data: compiled.SimpleStorage.code, gas: 300000})

После того, как контракт был добыт, я могу получить доступ к функциям контракта через объект хранилища. Я предполагал, что могу просто позвонить...

storage.set(10)

... чтобы установить переменную StoredData. Однако каждый раз, когда я пытаюсь это сделать, я получаю сообщение об ошибке «Неверный адрес».

Я уверен, что это потому, что я пытаюсь выполнить операцию записи внутреннего состояния контракта (операции чтения работают нормально).

Мне нужно отправить транзакцию, которая определяет новое состояние контракта, однако я не могу понять, как это сделать.

Как я могу выполнять транзакции записи в смарт-контрактах?

Ответы (1)

Попробуйте установить

web3.eth.defaultAccount = eth.accounts[0]

Похоже, ваша транзакция не знает, какую учетную запись использовать для подписи вызова. Любой вызов, изменяющий состояние контракта (операция записи), требует подписанной транзакции.

Альтернативным подходом может быть передача «объекта транзакции» в качестве последнего аргумента метода контракта:

storage.set(10,{from: accounts[0]});

Редактировать 1:

Когда я выбрал учетную запись «от», я получил следующую ошибку: «требуется аутентификация: пароль или разблокировка». Поэтому мне нужно было запустить personal.unlockAccount(eth.accounts[0],"password",15000). Вы можете прочитать об этом в разделе «Требуется аутентификация: пароль или разблокировка». Ошибка при попытке вызвать метод смарт-контракта через web3 .

Я знал, что это будет просто! Как мне это сделать, не устанавливая defaultAccount? Например, если бы я использовал несколько учетных записей в одном и том же экземпляре geth?
Вы можете вызывать web3.accountsи сохранять результаты в массив. Затем получите доступ к массиву для конкретной учетной записи. Когда вы вызываете метод, который выполняет транзакцию и нуждается в учетной записи, передайте объект, содержащий from:storage.set(10,{from: accounts[1]});
Это именно то, что я искал. Так просто! Если функция имеет несколько параметров, это просто... storage.set(a,b,c,d,{from: eth.accounts[0]})?
Да. См. документацию API web3.js: github.com/ethereum/wiki/wiki/… Обратите внимание на transactionObject. Это то, что вы можете передать в качестве последнего аргумента для вызова вашего контракта.
и как получить txID результата?
web3.eth.defaultAccount = accounts[0]должно бытьeth.defaultAccount = eth.accounts[0]
Это сработало и для меня. Просто хочу поделиться тем, как я изменил свой вызов, чтобы получить ответ на основе комментариев выше в web3.js на терминале Mac: Исходный вызов: contractInstance.getStep() . Новый вызов: contractInstance.getStep({from: web3.eth.accounts[0]}).