Summary
There are some oddities when using bytes32
as function parameters.
From Solidity Features - Byte Arrays:
PT Basic support for variable-length byte arrays. This includes
- bytes type for storage variables
- msg.data is of bytes type and contains the calldata
- functions taking arbitrary parameters (call, sha3, ...) can be called with bytes arguments.
- copying between msg.data and bytes storage variables
What is not
possible yet:
function parameters of bytes type
- local variables of bytes type
- index or slice access
Details
I use the following source code based on your source code:
contract ByteToInt {
uint public number;
bytes32 public thebytes32;
function ByteToInt(bytes32 _number) {
thebytes32 = _number;
number = uint(_number);
}
}
And flattened it to:
var byteToIntSource='contract ByteToInt { uint public number; bytes32 public thebytes32; function ByteToInt(bytes32 _number) { thebytes32 = _number; number = uint(_number); }}'
Ran it in geth --dev console
:
> var byteToIntSource='contract ByteToInt { uint public number; bytes32 public thebytes32; function ByteToInt(bytes32 _number) { thebytes32 = _number; number = uint(_number); }}'
undefined
Compiled it:
> var byteToIntCompiled = web3.eth.compile.solidity(byteToIntSource);
undefined
Inserted it into the blockchain:
> 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
And checked the values:
> byteToInt.thebytes32()
"0xa000000000000000000000000000000000000000000000000000000000000000"
> byteToInt.number()
7.237005577332262213973186563042994240829374041602535252466099000494570602496e+76
I executed the following statements in Java:
BigInteger num = new BigInteger("a000000000000000000000000000000000000000000000000000000000000000", 16);
System.out.println(num.toString(10));
And the results are:
72370055773322622139731865630429942408293740416025352524660990004945706024960
So 10
is being encoded as the first byte in your bytes32 variable, and the uint(...)
cast is converting the whole bytes32 data into a uint
.
Checking how web3 converts the decimal values into the parameters, I tried sending in 0xabc
into the constructor by using the decimal equivalent of 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
Try out the following:
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"