Neat Ethereum tricks. The transaction nonce.

Neat Ethereum tricks. The transaction nonce.

Whenever a user deploys a new contract to the Ethereum blockchain, that contract receives its own Ethereum address.

User 0x0a Deploying contract Reclaim –> contract address 0x0a1

As it turns out, these contract addresses ARE NOT a random address. The address of every contract we’ll deploy depends on two parameters:

  1. The Ethereum address from which the contract is being deployed.
  2. The nonce of the transaction.

 

What do we mean by nonce

The nonce of the transaction! Not to be confused with the nonce used in the mining process. In Ethereum, every transaction have a nonce associated with it. The nonce is one of the tools that helps to index and process transactions in the right order. The nonce itself IS NOT a random value. It grows by scalar one with every transaction we transmit to the blockchain. For the Ethereum test-net, the nonce begins with 0x100000 (1048576).

 

Calculating the new contract address

The new contract address can be computed in the following way:

def mk_contract_address(sender, nonce):
    return sha3(rlp.encode([normalize_address(sender), nonce]))[12:]

 

sha3 and rlp and encryption functions. The only two variables are the address of the sender and the nonce (basically the transaction number for that particular address).

I’ve installed the pyethereum library on ubuntu 16.04. and changed dir to directory cd /pyethereum/ethereum . There I launched python 2.7.12 and imported the utils.

$ cd /pyethereum/ethereum

$ python

>> import utils

Than I used the function utils.mk_contract_address(sender address, nonce) to get the addresses of my future contracts.

For the sender address: 0x43CCFE27708381164Fd079556C7Ef158A6d409Dc I can check for what the address of the next deployed contract will be.

nonce1 = 1048576 =>; 0x7930935a32ee489bd102002c2598602ff79c24fd

nonce2 = 1048577 =>; 0x0d7d52f686f54e44f604a6253857d5b119cb1da8

nonce3 = 1048578 =>; 0x9ddbce5eb6d16bd73e9256e091f9b39647daf026

I can continue this way on and on till I cover all the address space for the sender address.

 

What does it mean?

The first thing I did was to try and send transactions to future address. I sent 0.01 Eth from 0x43cc... to  0x7d47... (nonce = 1048584. You can use the code above to calculate the full address). The ether was sent without any problem. I can easily send the ethers to any valid ether address. The ethers, of course, can’t be reclaimed at this point since there’s no private key or code that is associated with that address.

Then I tried to deploy a contract to a particular pre-determined address (0x7d47...). I’ve used a basic meteor app with web3 library to deploy the contract.

Template.hello.events({
  'click button': function(event) {
    
    myContract = web3.eth.contract(newABI);
    myContract.new({
      from: web3.eth.accounts[0],
      data: newData,
      nonce: 1049856
     // to: "0x7D47BcC72D9c7758a3021B0A393af6aa2BE66F58"
    }, function(err, res){
      if(err){
        console.log(err);
      }else{}
      console.log(res);
    })
  },
});

The contract is a simple contract that allows reclaiming the ethers stored at the address 0x7d47....

contract Reclaim{
    
    address public owner = msg.sender;
    
    function kill(){
        suicide(owner);
    }
}

And I’m happy to say that the experiment went smoothly. As long as when deploying the contract to claim the coins, the nonce is set so that utils.mk_contract_address(sender address, nonce) = required address, the coins can be reclaimed!

You can watch the transactions I’ve created over here.

A list of the last three transactions.
A list of the last three transactions.

That made me think about few ways in which this trick can be utilized. From sending funds with higher anonymity to issuing assets and token BEFORE their contract code was even completed and I guess there’re much more options.

But there are limitations

Since the nonce is correlated with the number of transactions (and increases by one with each transaction) we need to make sure that when we deploying the Reclaim contract, we’ll do so when the next nonce matches the required address. otherwise we might lose our window of opportunity and the coins might be lost forever! When I tried to send the coins and then claim them back using a contract with a too high nonce, I failed to do so. It seems that the transaction stays in the transactions pool for 50 blocks, if by the time 50 blocks have passed we won’t transmit enough transactions to cover the gap in the nonce, our transaction will be dropped out.

	 	
nonce1 = 1048578  
nonce2 = 1048579  
***This gap needs to be filled within 50 blocks or the transaction will be dropped***
nonce150 = 1048728 
nonce151 = 1048529  

Leave a Reply

Your email address will not be published. Required fields are marked *