Я новичок в эфириуме.
Я определенно борюсь с последними 4 параметрами этой функции, поэтому я задаю проблему напрямую.
mapping(address => uint256) nonces;
/*
* Proxy transfer token. When some users of the ethereum account has no ether,
* he or she can authorize the agent for broadcast transactions, and agents may charge agency fees
* @param _from
* @param _to
* @param _value
* @param fee
* @param _v
* @param _r
* @param _s
*/
function transferProxy(address _from, address _to, uint256 _value, uint256 _fee,
uint8 _v,bytes32 _r, bytes32 _s) public transferAllowed(_from) returns (bool){
if(balances[_from] < _fee + _value) revert();
uint256 nonce = nonces[_from];
bytes32 h = keccak256(_from,_to,_value,_fee,nonce);
if(_from != ecrecover(h,_v,_r,_s)) revert(); // THE PROBLEM I’m STUCK ON SEVERAL HOURS IS HERE.
if(balances[_to] + _value < balances[_to]
|| balances[msg.sender] + _fee < balances[msg.sender]) revert();
balances[_to] += _value;
Transfer(_from, _to, _value);
balances[msg.sender] += _fee;
Transfer(_from, msg.sender, _fee);
balances[_from] -= _value + _fee;
nonces[_from] = nonce + 1;
return true;
}
_v
мне нужно использовать web3.eth.sign с web3.eth.sign("0x395BE1C1Eb316f82781462C4C028893e51d8b2a5",keccak256("data"))
. Но если это не так, я не знаю, что мне нужно использовать_r
о чем._s
что это обратный вызов HTTP (прочитав документацию). Но кажется, что я не могу просто оставить его равным 0, так как я не знаю, что вызывать.mapping(address => uint256) nonces;
и uint256 nonce = nonces[_from];
на самом деле делать. И, очевидно, мне нужно знать значение, чтобы установить_v
_r
_s
Так что у тебя есть
Mapping(address => uint256) nonces означает, что значение uint256 связано с адресом. Позволь мне привести пример
Предположим, у вас есть адрес 0xa1bc и вы хотите сопоставить какое-то значение с этим адресом, пусть значение будет 1234. Вот как это делается
nonces["0xa1bc"] = 1234;
и получить значение, связанное с адресом
uint256 temp = nonces["0xa1bc"]
Здесь я присвоил значение temp, поэтому temp будет 1234. Если сопоставление отсутствует, значение будет 0 (ноль).
Вы можете увидеть именно такое поведение в функции transferProxy ,
uint256 одноразовый номер = одноразовый номер[_from];
nonce[_from] = одноразовый номер + 1;
Итак, в функции сначала читается одноразовый номер, связанный с адресом _from, выполняется какая-то работа и, наконец, увеличивается одноразовый номер на единицу и сохраняется по тому же адресу _from.
Теперь, переходя к вашей следующей проблеме с _v, _r и _s,
Вы правы насчет web3.eth.sign . Вы можете подписать часть сообщения с помощью web3.eth.sign(data, privatekey) и его варианта. Это даст вам объект подписи. Эту сигнатуру можно разложить на v, r и s. Итак, как вы можете получить эти значения? Обращать внимание.
знак переменной = web3.eth.sign (данные, закрытый ключ);
вар v = знак.v;
вар г = знак.г;
вар с = знак.с;
Эти v, r и s являются значениями, которые вам нужно отправить в функцию TransferProxy в контракте.
Итак, в основном, зачем вам нужны эти значения? Там вы можете увидеть функцию ecrecover , которая принимает эти значения в качестве параметров. Это встроенная функция Solidity. Он дает адрес пользователя, подписавшего данные. Здесь h — хэш данных, которые вы хотите подписать.
Но здесь мы видим, что вы не отправили хеш h контракту. Почему? Потому что вы можете создать исходное сообщение с данными, представленными в самом контракте. И это исходное сообщение _from,_to,_value,_fee,nonce . Это означает, что на стороне клиента вы сохранили или знали эти значения заранее.
var sign = web3.eth.sign(_from+_to+_value+_fee+nonce, privatekeyOf_from);
Итак, вызов функции контракта на лицевой стороне будет выглядеть так:
ContractInstance.transferProxy.sendTransaction(от, до, значение, плата, одноразовый номер, v, r, s, {от:.....});
if(_from != ecrecover(h,_v,_r,_s)) revert(); гарантирует, что пользователь с адресом _from действительно подписал данные или нет. Если не отменить (отменить изменения) транзакцию.
Что касается вашего первого вопроса, несколько параметров будут объединены, а затем хешированы.
Во-первых, keccak256 обычно принимает только один аргумент (данные для хеширования). Я понятия не имею, что делает использование нескольких параметров. Добавление данных? Если да, то как? Хэширование хэшей? все сразу или перефразировать после каждого результата?
Из документов в Solidity:
keccak256(...) возвращает (bytes32): вычислить хэш Ethereum-SHA-3 (Keccak-256) (плотно упакованных) аргументов
Следовательно, данные для хеширования представляют собой плотно упакованные параметры, (_from,_to,_value,_fee,nonce)
поэтому keccak256(_from,_to,_value,_fee,nonce)
вычисляется хэш бинарного слова, полученного путем объединения всех этих пяти параметров.
Во-вторых, я думаю, что для получения _v мне нужно использовать web3.eth.sign с web3.eth.sign("0x395BE1C1Eb316f82781462C4C028893e51d8b2a5",keccak256("data")). Но если это не так, я не знаю, что мне нужно использовать. Третий, понятия не имеет о _r. В-четвертых, я думаю, чтобы понять, что _s относится к обратному вызову HTTP (прочитав документацию). Но кажется, что я не могу просто оставить его равным 0, так как я не знаю, что вызывать.
Эти параметры получены из подписи. При подписании web3 транзакция предоставляет подпись и параметры r, s и v. Эти параметры также могут быть получены из самой подписи, см. документацию web3 о том, как получить r, s и v, а также этот ответ
И САМОЕ СЛОЖНОЕ. Как точно определить параметры nonce в keccak256? (даже если я понятия не имею, как это назвать), потому что мне трудно понять, что такое отображение (адрес => uint256) nonces; и uint256 nonce = nonces[_from]; действительно. И, очевидно, мне нужно знать значение, чтобы установить _v _r _s
отображение принимает в качестве входных данных адрес и возвращает число, это число является одноразовым номером. Поэтому nonce[_from]
запрашивает одноразовый номер для адреса _from
. Это одноразовое значение в основном является счетчиком, который увеличивается каждый раз, когда транзакция выполняется с адреса _from
.
Надеюсь это поможет.
keccak256
вы имеете в виду конкатенацию? Если да, то в байте или в строке?the mapping takes as input an address and returns a number, that number is the nonce. Therefore, nonce[_from] is requesting the nonce for the address _from. This nonce value is basically a counter that increments every time a transaction is executed from the address _from.
Это не говорит о том, как я получаю одноразовый номер для хеширования.web3.eth.personal.ecRecover
если для вычисления хеша. Требуется ли web3.eth.sign для обратного?nonce = w3.eth.getTransactionCount('your account address')
. Теперь sign подпишет сообщение и даст вам значения r, s и v. ecrecover in Solidity восстановит адрес учетной записи, которая инициирует транзакцию. В вашем коде это восстановление адреса является доказательством того, что подпись действительна. Надеюсь это поможет.
пользователь 2284570
0x395BE1C1Eb316f82781462C4C028893e51d8b2a5
?биплав
пользователь 2284570
биплав
пользователь 2284570
биплав
биплав
пользователь 2284570