Hot answers tagged

11

RLP was chosen because of (1) simplicity of implementation, and (2) guaranteed absolute byte-perfect consistency. Source is Ethereum Wiki: RLP is intended to be a highly minimalistic serialization format; its sole purpose is to store nested arrays of bytes. Unlike protobuf, BSON and other existing solutions, RLP does not attempt to define any ...


11

Let's start with having a look at what we get in geth console for block number 40. Now let's consider a Go program. I Explained everything in code comments about how it is constructing keys and accessing values from Leveldb. package main import ( "github.com/syndtr/goleveldb/leveldb" "fmt" "encoding/binary" "github.com/ethereum/go-...


7

The EVM is always 256 bits big-endian. From the Yellow Paper, Appendix H: "When interpreting 256-bit binary values as integers, the representation is big-endian." RLP is different from the Contract ABI. From above RLP wiki, encodings "must be represented in big endian binary form with no leading zeroes." There are no (other) explicit rules about padding ...


7

It will be easier to understand if we make these two definitions (note: this might not be fully correct, but is enough for the following explanation): the EVM is the machine executing the instructions, which has inputs and outputs the state manager as the one putting data in/out of the blockchain. Many of the interactions with the blockchain (and state ...


6

I wrote this on the gitter.im channel, so here it is again anyway. Caveat is I have not looked at recent geth code for this, so there may be subtle discrepancies with actuality. A key paragraph is this "Message IDs are assumed to be compact from ID 0x10 onwards (0x00-0x10 is reserved for ÐΞVp2p messages) and given to each shared (equal-version, equal name) ...


4

Different computers store binary data differently. The purpose of the RLP as stated in the referenced document is to The purpose of RLP (Recursive Length Prefix) is to encode arbitrarily nested arrays of binary data, and RLP is the main encoding method used to serialize objects in Ethereum. In other words, it turns any binary data structure into a string ...


4

It appears that encoding the integer 0 no longer equates to \x00 (as the documentation would imply). This can be seen both in your example, and in the fact that it can't be decoded: >>> decode('\x00') '\x00' >>> decode('\x00', big_endian_int) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/...


4

You can find the block header's structure in the Yellow paper, 4.4 (page 5). I don't have time to go through eveyrthing, but if I do not make any mistake, for example, you could bind the following: cd7bd64fba4cc782fe5474d3640882afece5887180591e72f80ce6916cf73526 --> Parent hash 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 --> ...


3

Partial answer. Why does the ChainId is 0x1c or 28 ? Given this list it don't understand. The link you point to shows network ID, which isn't the same as chain ID. Further, 28 isn't the chain ID, it's the v value. See EIP-155 for details of expected v values, and this answer for a definition of v, r, and s.


2

RLP deals only in structures made up of bytes (binary data). It doesn't care whether those bytes represent strings, integers, big integers, floating point numbers or whatever. This is in the sentence prior to the one you quoted, The purpose of RLP (Recursive Length Prefix) is to encode arbitrarily nested arrays of binary data... On your question: ......


2

You can't. RLP can't have leading zeros. It is designed to encode values in a shortest way, so redundant leading zeros make RLP not canonical. What's more, transaction's RLP starts with payload containing size of transaction. By prepending anything there, you simply alter/overwrite the payload and make transaction undecodable edit. Encoding example: 257 ...


2

The other answer gives useful information, but to directly answer your question: RLP encoding does not give any information about types. It only encodes strings (byte sequences) and lists of lists/strings. How you interpret those strings (byte sequences) is up to the application.


2

The byte 0xe6 was simply following the 3rd rule describing an rlp list serialized. tx = new ethTx({}); console.log('RLP-Encoded Tx: 0x' + tx.serialize().toString('hex')) Gives: 0x c9 808080808080808080 and as the payload 808080808080808080 is 9 bytes or 0x09 so below 55 bytes, serializing a rlp list is just 0xc0 + 0x09 -> 0xc9. In my exemple, the payload ...


2

I read code bad: when we got key = pack_nibbles(with_terminator('\x01\x01\x02') value = rlp.encode(['hello']) which is tantamount to: key = '\x01\x01\x02' value = '\xc6\x85hello' this value stored like [key, value] pair in root_node. Then we get common RLP of root_node (e.g. rlp(['\x01\x01\x02', \xc6\x85hello'])). and obtain key for new entry line in ...


2

It says that RLP is simple unambiguous It's simpler than other algorithms because it doesn't define any data types other than bytes and arrays. It's unambiguous because the same input data is always serialized to the same sequence of bytes. In many languages key/value maps don't have explicit ordering. This means 2 entries: key1: value1 key2: value2 ...


2

https://www.npmjs.com/package/solidity-rlp Here is a package I am maintaining to decode rlp bytes in solidity. you can checkout the code and usage instructions here: https://github.com/hamdiallam/solidity-rlp


2

Does someone know if there is any documentation on encryption in the inter-node protocol? You might have already found these, but here are few sources I've used in the past: https://github.com/ethereum/devp2p/blob/master/rlpx.md (The RLPx Transport Protocol) https://github.com/ethereum/devp2p/blob/master/devp2p.md (devp2p Application Protocol) Gitter ...


2

131 can't be encoded as just 0x83. From https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP: For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding. 0x83 is outside of that range, so this "self encoding" can't be used. Otherwise, if a string is 0-55 bytes long, the RLP encoding consists of a single byte with ...


1

Below are the steps to calculate blockHash, given a blockNumber: Step1. eth.getBlock(400000) Output:{ difficulty: '6022643743806', extraData: '0xd583010202844765746885676f312e35856c696e7578', gasLimit: 3141592, gasUsed: 0, hash: '0x5d15649e25d8f3e2c0374946078539d200710afc977cdfc6a977bd23f20fa8e8', logsBloom: '...


1

Thanks to @Ismael who clarified how the RLP encoding handles data during contract initialization. It seems the encoding protocol can distinguish between empty byte array and address. The rules of the EVM are then different and irrelevant here. Implementations can choose to handle payloads differently. For example, javascript web3 address entries of 0 & ...


1

The mistake is treating the sending account as a string. It's a hexadecimal representation of some bytes. You can use bytes.fromhex to convert it. Otherwise I think your code is fine. This code works: import rlp from sha3 import keccak_256 # Convert from hex to bytes. Be sure to drop the leading 0x. sender = bytes.fromhex("...


1

I don't know if there is any native library available in Solidity, but there are node-js libraries available will help you do that. I also found this solidity code when doing a search on RLP, have a look at the code snippet below: https://github.com/Giveth/milestonetracker/blob/master/contracts/RLP.sol Libraries: https://www.npmjs.com/package/rlp ...


1

A string contains a 1 word (32 byte) length, followed by its bytes packed right zero padded to the nearest 32 byte word. Keep in mind that utf-8 characters like emoji are multiple bytes long. var ethers = require('ethers'); function getString(length) { var s = ''; while (s.length < length) { s += '0'; } return s; } for (var l = 0; l < 5 *...


1

Taken from the documentation, you have the following axioms: if a string is 0-55 bytes long, the RLP encoding consists of a single byte with value 0x80 plus the length of the string followed by the string. The range of the first byte is thus [0x80, 0xb7]. And If the total payload of a list (i.e. the combined length of all its items being RLP encoded)...


1

RLP encoding is defined as follows: For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding. Otherwise, if a string is 0-55 bytes long, the RLP encoding consists of a single byte with value 0x80 plus the length of the string followed by the string. The range of the first byte is thus [0x80, 0xb7]. If a string is more ...


1

First of all this is note extension node - this is leaf. You can use state._get_node_type() function in Python to understand that. If this node is really extension it must look like: extension_node:[key,value] , or because value in extension nodes = hash of next node (usually next node type is branch_node, but it may be leaf_node if it size more that don'...


1

It is just once the length of the byte array - the wiki describes it a bit confusing. Better look at the yellowpaper PDF (appendix RLP): https://ethereum.github.io/yellowpaper/paper.pdf Or an implementation: https://github.com/walleth/kethereum/blob/master/rlp/src/main/java/org/kethereum/functions/rlp/RLPFun.kt#L24


1

I think keys are needed to organize tree - to know how to move nodes in trie without knowledge of stored information, read about Patricia-Tree. In examples, they use keys to organize trie.


1

In practice, leading zeroes may cause some problems across OS, for example, regarding big endian VS. little endian. In an other link (which I don't remember where it lies), it's said to an implementation just ignore such leading zeroes. From the Ethereum yellow paper: When interpreting RLP data, if an expected fragment is decoded as a scalar and ...


1

I ended up opening an issue for this and it is confirmed to be the problem @karalabe guessed it is: https://github.com/ethereum/go-ethereum/issues/14599 Will be fixed soon


Only top voted, non community-wiki answers of a minimum length are eligible