Datatypes in event parameters

ppohjappohja Posts: 10Member
Hi all,
I've been playing around with the web3's event logging functionality. The documentation is a bit sparse, so I decided to write down some notes from the effort I've spent with this. The JavaScript API documentation for contract events outlines some of the functionality, but especially the different datatypes were of interest to me.

So, I wrote an example contract for testing out how the contract events function in practice. Also, made a NodeJS-based monitor, which listens to each of these contract events and prints out what it gets.

I'm using two ways to determine the datatype of the incoming object: Object.prototype.toString and input.constructor.name. These give the same result when the returned value is JavaScript native type (Boolean, String, Array), but with numbers they differ (Object/BigNumber).

There were maybe few things to note:
- uint and int overflows do not happen.
- bytes and bytes are returned as hex strings ("0x666f").
- I couldn't get enums working.

Here's a more detailed summary what I've so far found out:
- Solidity bool translates to Javascript Boolean.
- Solidity int and uint translates to Javascript BigNumber. Forgetting to handle big numbers correctly can be cumbersome. When sending transactions from Geth, it is good idea to remember that literals are small. Using BigNumber('1212') helped. See here for more info.
- When sending bigger numbers that the ABI accepts (e.g. 0xfff to uint8), the number is clipped to its maximum value (255).
- Bytesn are returned as JavaScript Strings with string length being 2*n+2. E.g. Bytes1 value 0xe results "0xe0".
- Strings are returned as JavaScript Strings. Sending numeric values (0x666f6f62617278 for foobar) results an empty string.
- Bytes are returned as JavaScript Strings.
0x00 results "0x".
0x666f6f62617278 results "0x666f6f62617278".
BigNumber('9773762345704728841615836916958090958110492435809033220549909040401340504702567') results
"0x5468697320737472696e672069732033332063686172616374657273206c6f7e67".
"" results "0x".
"foobar" results "0x666f6f626172"
"This string is 33 characters long" results "0x5468697320737472696e672069732033332063686172616374657273206c6f6e67"
- Enums I couldn't get working. When testing enums, I started observing "removed tx from pool: low tx nonce" error messages in the log. Need to study this further.
- Arrays are returned as JavaScript Arrays. Tested only the boolean array though.
- When printing out big numbers with JSON.Stringify, the output changes to scientific notation at around 1e21. The underlying object datatype is BigNumber, so I'm hoping that it's the display routine only which is causing this. Maybe somebody could verify?


For more concrete show, here's an example outputs from my tests:

Geth prompt:
> eventtestInstance.booleanTest.sendTransaction(true, {from: eth.accounts[0], gas: 1000000}); "0x5b7416ec5b9d89654429ad694f674ee0190b1497d8b20dae7a6e0305880c16bf"
Monitor result:
{"address":"0xa5fa4c56bec5dc4e3ff3e26edabf638e23348410", "blockNumber":610, "logIndex":0, "blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000", "transactionHash":"0x5b7416ec5b9d89654429ad694f674ee0190b1497d8b20dae7a6e0305880c16bf", "transactionIndex":0, "event":"BooleanTestEvent", "args":{"input":true}} RESULT: true (Boolean/Boolean)

In the first run, I was connecting the monitor to the same instance in which I was running the sendTransaction. This results the monitor being notified immediately about the transaction. However, the blockHash is 0x0.

Here's another example for the case where the monitor is attached to a different node and thus gets notified only after the transaction has been included in a block:

Geth prompt:
> eventtestInstance.BytesTest.sendTransaction(new BigNumber('9773762345704728841615836916958090958110492435809033220549909040401340504702567'), {from: eth.accounts[0], gas: 1000000}); "0x94f8ee4afc16692841903434882eec57df843dc14f44f9939a34eea78a082e2d"

Monitor result:
{ "address": "0xa5fa4c56bec5dc4e3ff3e26edabf638e23348410", "blockNumber": 730, "logIndex": 0, "blockHash": "0x13cb998554c126d987390b616b46e8213a5a0a764e5947b36353790347e1b2b4", "transactionHash": "0x94f8ee4afc16692841903434882eec57df843dc14f44f9939a34eea78a082e2d", "transactionIndex": 0, "event": "BytesTestEvent", "args": { "input": "0x5468697320737472696e672069732033332063686172616374657273206c6f7e67" } } 0x5468697320737472696e672069732033332063686172616374657273206c6f7e67 (String/String)

Hopefully I can find my post next time I need this information. Maybe next time I'll also post how chain reorganisations show at the event callbacks.

Comments

  • ConradJohnsonConradJohnson Posts: 130Member ✭✭
    This is nice @ppohja . I'm just learning events and trying to monitor changes from them from node. Do you have any examples with just 1 event and 1 event monitor for node. I'd like to have a web interface (Mist browser obv...) change a value on a contract and the node server to see that change and output a log on that trigger... I'm having a hard time just finding this simple example so that I can wrap my head around all of the moving parts.
Sign In or Register to comment.