Я создаю следующий контракт с _number
as 10
. Когда я проверяю значение number
, я получаю 72370055773322622139731865630429942408293740416025352524660990004945706024960
. Это проблема с моим контрактом или это ошибка web3?
contract Thing{
uint public number;
function Thing(bytes32 _number){
number = uint(_number);
}
}
72370055773322622139731865630429942408293740416025352524660990004945706024960
is 0xa000000000000000000000000000000000000000000000000000000000000000L
- или 10
в шестнадцатеричном формате со сдвигом влево. Не видя ваш код web3, трудно сказать, почему он был проанализирован таким образом, но вполне вероятно, что web3 обработал ваш ввод как однобайтовую байтовую строку и выровнял ее по левому краю в аргументе bytes32.
Есть некоторые странности при использовании bytes32
в качестве параметров функции.
Из возможностей Solidity — массивы байтов :
PT Базовая поддержка массивов байтов переменной длины. Это включает
- тип байтов для хранения переменных
- msg.data имеет тип bytes и содержит данные вызова
- функции с произвольными параметрами (call, sha3, ...) могут вызываться с байтовыми аргументами.
- копирование между переменными хранения msg.data и bytes
Что еще
not
возможно:
function parameters of bytes type
- локальные переменные типа bytes
- доступ к индексу или срезу
Я использую следующий исходный код на основе вашего исходного кода:
contract ByteToInt {
uint public number;
bytes32 public thebytes32;
function ByteToInt(bytes32 _number) {
thebytes32 = _number;
number = uint(_number);
}
}
И сгладил его до:
var byteToIntSource='contract ByteToInt { uint public number; bytes32 public thebytes32; function ByteToInt(bytes32 _number) { thebytes32 = _number; number = uint(_number); }}'
Запустил в geth --dev console
:
> var byteToIntSource='contract ByteToInt { uint public number; bytes32 public thebytes32; function ByteToInt(bytes32 _number) { thebytes32 = _number; number = uint(_number); }}'
undefined
Скомпилировал это:
> var byteToIntCompiled = web3.eth.compile.solidity(byteToIntSource);
undefined
Вставил его в блокчейн:
> var byteToIntContract = web3.eth.contract(byteToIntCompiled.ByteToInt.info.abiDefinition);
var byteToInt = byteToIntContract.new(10, {from:web3.eth.accounts[0], data: byteToIntCompiled.ByteToInt.code, gas: 1000000},
function(e, contract) {
if (!e) {
if (!contract.address) {
console.log("Contract transaction send: TransactionHash: " +
contract.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined! Address: " + contract.address);
console.log(contract);
}
}
}
)
...
Contract mined! Address: 0x49617e1728c53a3e31ccf21faf6ba344af90f04c
И проверил значения:
> byteToInt.thebytes32()
"0xa000000000000000000000000000000000000000000000000000000000000000"
> byteToInt.number()
7.237005577332262213973186563042994240829374041602535252466099000494570602496e+76
Я выполнил следующие операторы в Java:
BigInteger num = new BigInteger("a000000000000000000000000000000000000000000000000000000000000000", 16);
System.out.println(num.toString(10));
И результаты таковы:
72370055773322622139731865630429942408293740416025352524660990004945706024960
Итак 10
, кодируется как первый байт в вашей переменной bytes32, а uint(...)
приведение преобразует все данные bytes32 в файл uint
.
Проверяя, как web3 преобразует десятичные значения в параметры, я попытался отправить в 0xabc
конструктор, используя десятичный эквивалент 2748
:
var byteToInt = byteToIntContract.new(2748, {from:web3.eth.accounts[0], data: byteToIntCompiled.ByteToInt.code, gas: 1000000},
function(e, contract) {
if (!e) {
if (!contract.address) {
console.log("Contract transaction send: TransactionHash: " +
contract.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined! Address: " + contract.address);
console.log(contract);
}
}
}
)
...
Contract mined! Address: 0xb086848ed791c87a6659ed17fb6fd85e37aae97b
...
> byteToInt.thebytes32()
"0xabc0000000000000000000000000000000000000000000000000000000000000"
> byteToInt.number()
7.7684731744176002203118424512664641303902811977827214350690781458433906311168e+76
Попробуйте следующее:
var byteToInt = byteToIntContract.new(0x0000000000000000000000000000000000000000000000000000000000000abc, {from:web3.eth.accounts[0], data: byteToIntCompiled.ByteToInt.code, gas: 1000000},
function(e, contract) {
if (!e) {
if (!contract.address) {
console.log("Contract transaction send: TransactionHash: " +
contract.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined! Address: " + contract.address);
console.log(contract);
}
}
}
)
...
> byteToInt.thebytes32()
"0xabc0000000000000000000000000000000000000000000000000000000000000"
Ник Джонсон
АФ