Browsed by
Category: ethereum tricks

Modifiers – Go With The Flow

Modifiers – Go With The Flow

What is a modifier

Modifiers are a neat feature in Solidity that allows us to change the flow of our code execution. The modifiers (as the name suggest) can modify the code of a function.

Look at the following contract:

contract A{
    
    uint public number;

    modifier zeroNum(){
        number = 0;
        _;
    }

    function plusNumber(uint _input){
        number = number + input;
    }  
}
In the code above, the modifier zeroNum is executed right before the rest of the function. It reset the number value back to zero. If it wasn’t for that modifier, the numbers would have just continue to add up.
Modifiers are mostly used as a gateways in our smart contracts:
contract B{

    address public owner = msg.sender;

    modifier onlyOwner(){
        assert(msg.sender == owner);
        _;
    }

    function register()onlyOwner(){
    //Do stuff
    }
}

In this example, only the owner of the smart contract can execute the rest of the function code.

Here’s another example in which the modifier that prevents anyone below the age of eight-teen to register:

contract C{

    address public owner = msg.sender;
    string public name;
    uint public age;

    modifier onlyOwner(){
        assert(msg.sender == owner);
        _;
    }

    modifier notMinors(uint _age){
        require(_age>18);
        _;
    }

    function register(string _name, uint _age)onlyOwner() notMiner(_age){
        name = _name;
        age = _age;
    }
}

The underscore.

Each modifier contains an underscore, this is where the rest of the code is inserted. The underscore can also be nested inside the modifier.
contract D{
    
    uint public input;
    uint public number;

    modifier onlyOwner(uint _input){
        assert(msg.sender == owner);
        input = _input + 1;
        _;
        input = _input + 2;
    }

    function doStuff(uint _input) onlyOwner(_input){
        number = input +1; //At the time of the code execution
    }
}

The difference between require and assert

Two powerful commands are assert and require. Both aren’t necessarily related to modifiers; in fact you can use these two in any function. However, they’re beneficial when trying to follow the execution flow of the code. Both will perform some logical test and will either allow the code to continue or throw the code. Throwing is the process by which the states of the EVM is reverted to the ones before the code execution. Also, currently throwing takes all of the gas associated with that transaction. In the future, the require command will refund the users of their unused gas and might even return some value.

Multiple modifiers

We can use more than one modifier in function. Modifiers will be loaded and nested according to their order.
function doStuff() modifierOne() modifierTwo() modifiersThree(){
    //TO DO
}

Predefined modifiers in Solidity:

 
public       - called by everyone
external     - Can only be called by external function (or by "this.functionName")
private      - can only be called by functions within the contract or from its derivatives 
internal     - Can only be called internally 

payable      - can accept Ethers
constant     - don't send transactions function is executed locally

Side note – The difference between require and assert

Two powerful commands are: assert and require. Both aren’t necessarily related to modifiers; in fact you can use these two in any function. However, they’re beneficial when trying to follow the execution flow of the code. Both will perform some logical test and will either allow the code to continue or throw the code. Throwing is the process by which the states of the EVM is reverted to the ones before the code execution. Also, currently throwing takes all of the gas associated with that transaction. In the future, the require command will refund the users of their unused gas and might even return some values.
For now there's no change (both throws). In the future:
require - revert but won't take all gas. It will refund the user and return a value
assert - like the old throw - revert changes and consume all gas
Get your Bitcoin address using Ethereum smart contract

Get your Bitcoin address using Ethereum smart contract

Ethereum and Bitcoin are both using the same type of encryption, the ECC (Elliptic Curve Cryptography) over the same graph (256k1). While it’s not really recommended, the same key pair can be used both for Bitcoin and Ethereum.

A simple Solidity code can be used to get the Bitcoin address of a public key. Such a code can run locally (as a constant function) on the Ethereum Virtual Machine to save gas, or as a regular Ethereum transaction.

The code in this example requires the user to insert their public key in its uncompressed format as an input; then it produces the binary address that matches that uncompressed public key for the main Bitcoin network. The code can be easily modified to work with compressed public keys as well (just remove the yPoint and add the side of the ECC graph). The code can also be amended to give the binary address of other testnet/namecoin.

 

How to create a Bitcoin address

The most basic process of deriving Bitcoin address from a public key is set in the following technical documentation.

 As you can clearly see, there’s very little to it than just hashing and appending.

Recreating the process in Solidity

First, let’s generate a random keypair using bitaddress.org. Under the tab “wallet details” we can see the uncompressed public key.

The public key
xPoint = C4BB8E42F7DA5504A456C16BE533549DA4FE580279382478F3365FF7CCBF032D
yPoint = 68A73547E809F1ABFAA51D10019E8AC682D1205448042326E9E3B91841CB9FA7

Now let’s create our smart contract in Solidity:

pragma solidity ^0.4.11;

contract BitValid{
	
	bytes32 constant mask4 = 0xffffffff00000000000000000000000000000000000000000000000000000000;
	bytes1 constant network = 0x00;


	function getBitcoinAddress(
			bytes32 _xPoint,
			bytes32 _yPoint)
			constant
			returns(
				bytes20 hashedPubKey,
				bytes4 checkSum,
				bytes1 network)
	{
		hashedPubKey 	= getHashedPublicKey(_xPoint, _yPoint);
 		checkSum 	= getCheckSum(hashedPubKey);
 		network 	= network;
	}

	function getHashedPublicKey(
			bytes32 _xPoint,
			bytes32 _yPoint)
			constant
			returns(
				bytes20 hashedPubKey)
	{
		var startingByte = 0x04;
 		return ripemd160(sha256(startingByte, _xPoint, _yPoint));
	}

	function getCheckSum(
			bytes20 _hashedPubKey)
			constant
			returns(
				bytes4 checkSum)
	{
		var full = sha256((sha256(network, _hashedPubKey)));
		return bytes4(full&mask4);
	}
}

The function getBitocinAddress() takes the x and y coordinate of the public key from the user, both are 32 bytes long (the uncompressed public key) and will return 3 variables, the hashed public key (bytes20), the checksum (bytes4) and the network starting byte (bytes1).

The network starting byte is currently hard codded to 0x00 (the main starting code). You can change this code to work with any other test network.

The hashed public key is obtained by hashing the public key (both x and y coordinates) with the starting byte 0x04 twice (as described in the technical documentation). Once with sha256 and then again with ripemd160. The finale result is 20 bytes long.
function getHashedPublicKey(
		bytes32 _xPoint,
		bytes32 _yPoint)
		constant
		returns(
			bytes20 hashedPubKey)
{
	var startingByte = 0x04;
	return ripemd160(sha256(startingByte, _xPoint, _yPoint));
}
After we got the hashed public key, we’ll prepend the network byte to it and hash it again twice using the sha256 function. The result of 32 bytes long is used to construct the checksum, a special 4 bytes that are used to allow another user to verify that the Bitcoin address they’re sending to is indeed a valid address.
bytes32 constant mask4 = 0xffffffff00000000000000000000000000000000000000000000000000000000;

function getCheckSum(
		bytes20 _hashedPubKey)
		constant
		returns(
			bytes4 checkSum)
{
	var full = sha256((sha256(network, _hashedPubKey)));
	return bytes4(full&mask4);
}
We don’t need all of the 32 bytes, only the first 4 bytes, but slicing variables is a hard thing to do in Solidity. Luckily, Solidity does allow for easy bit manipulation and masking. You’ll need to create a mask of 32 bytes to match the 32 bytes of the sha256 output. This mask should take only the first 4 bytes, as they’re the real checksum.
The full result (32 bytes) = 0x4c30ed507a508af52063560ff8f1c09e66be0587868a0b8ca21ab337440e4e8e
Mask for the first 4 bytes = 0xffffffff00000000000000000000000000000000000000000000000000000000
checksum = 0x4c30ed50

The results

At the end of the day, we have the following three components to return to the user, the network byte (currently hard coded), the hashed public key and the checksum. These are the three components that make up a Bitcoin address.

However, this isn’t the last step. In Bitcoin, a special type of encoding is used called base58. The current code doesn’t convert the result into base58 (I’ll leave it for another day), so we’ll be forced to do this step manually.

The following website provides some tools to convert our bytecode into base58. This is basically the final Bitcoin address.

At the end of the day

Using Solidity to retrieve the Bitcoin address that matches a specific public key (and therefore, a private key as well) might be useful when you’re trying to create a smart contract that maps some events between entities on both blockchains and I suspect might have some value when dealing with identities. The procedure isn’t cheap on gas but can be done locally using the EVM. It’s a shame that there’s no access to the bytecode of the transactions in Solidity since it could have made the process of finding the Bitcoin address of the message sender automated.

Proof of data integrity – Solidity code

Proof of data integrity – Solidity code

Update:

I’ve simplified to code to take more advantage of the boolean data type Ethereum offers.

Now the mapping is (bytes32=>bool) instead of (bytes32=>bytes32).

The boolean array is used to prove the existence of a single document. The root of the tree is stored once and is hashed again with the new input.

The complete code can be found on Github. The old test files can be used on this code as well

struct tree{
    bytes32 root;
    mapping(bytes32=>bool) dataExist;
}

bytes32 public empty;

mapping (address=>tree) public users;    
****

function addData(
			uint256 _input,
			address _user)
			returns (bool success)
{
	var data   = keccak256(_input);        
	var oldRoot = getUserRoot(_user);
    var newRoot = hashTheTwo(data, oldRoot);

    users[_user].dataExist[data] = true;

    users[_user].root = newRoot;

    return true;
}
****

function checkDataIntegrity
        (uint256[] _data, 
        address _user)
        constant         
        returns (bool complete){ 

	var oldRoot = empty;                         
    
    for (uint i = 0; i < _data.length; i++) {     
        var data = keccak256(_data[i]);
        if(users[_user].dataExist[data]){
            var root = hashTheTwo(data, oldRoot);
            oldRoot = root;
            continue;             
        }else{
            return false;
        }
    }

    if(root == getUserRoot(_user)){
    	return true;
    }else{
    	return false;
    }
}
Contract: test 01
    The first stage is Deploying Data
      ✓ Deploys the Data contract
      ✓ Register account 0 user (69ms)
    Adds three datas to account 0 user tree
      ✓ get account 0 user root - should be undefined (79ms)
      ✓ Adds the first data 1 (108ms)
      ✓ Adds the second data 2 (86ms)
      ✓ Adds the third data 5 (79ms)
    Check data integrity
      ✓ Pass the complete array [1, 2, 5] - expect true (122ms)
      ✓ Pass the  array [1, 2] - expect false (93ms)
      ✓ Pass the  array [1, 5, 2] - expect false (83ms)


  9 passing (818ms)
    

Storing data on the blockchain

Current blockchain architecture allows us to decentralized valuable information. The most obvious example is the blockchain itself, which is nothing more than just a database that each user can interact with. The users can download a copy of the blockchain, parse it and extract any information that is meaningful to them, to add information to that database, to check its integrity and so on.

But adding information directly to the blockchain is a problematic process. For one, it’s highly expensive. Whether you’re using Bitcoin or Ethereum as the blockchain on which to store your data, you’ll soon find out that any attempt to save more than a few bytes of data at a time can get ridiculously expensive. For that reason, many have started to use the blockchain as a method to “proof existence” of said document. In this process, instead of publishing the full document on the blockchain, the document is hashed using a prespecified hashing algorithm. This practice means that the owner of the document uses the blockchain not as a mean to store his or hers document, but to prove:

  1. Ownership over the said document (As long as he keep the private key from which the transaction was deployed)
  2. The existence of the said document at a specific point in time (by looking at the block header timestamp)
  3. The integrity of that specific document, as each minor change to the original file, will result in an entirely different hash.

By keeping the document yourself, you’re also able to better handle your privacy, as now instead of publishing your own private documents on a public blockchain for all to see, you’re only posting the result of a hash function, which is extremely difficult to Didact the contains of the original document from.

Such a system might be sufficient for sporadic use. But what happens if we want to create a system that new documents are continuously added to it. And we want to be able to prove the integrity of each individual document, both by itself and in conjunction to those preceding it?

 

Binary trees.

Binary trees are not a new thing in blockchains. Merkle trees and roots are used in Bitcoin and Ethereum to store and organize transactions and to allow for merged mining. In Ethereum the trees are also used to access the storage (variables) and states of the blockchain.

One of the great characteristics of binary trees is the ability to use them, plus some hashing algorithm to prove the integrity of the data stored in it.

Let’s have a look at the most common example, the Bitcoin Merkle tree. In this tree, each leaf represents one transaction. These transactions are hashed together again and again until finally, the final hash (the root) is produced. Storing the root require much less space than when storing all of the transactions data. But if I want to check that a specific transaction is indeed a part of a specific block, I can reconstruct that said block Merkle root by myself. In this case, that means that instead of storing all of the transactions that took place in the blockchain, I maintain only copies of the transaction that is relevant to me (and usually it requires less than a half of the transactions in a block).

In Bitcoin this tree is used both to proof the integrity of the block and to make it easier to validate transaction without having a full copy of the blockchain

 

My proposal 

Knowing the advantages of binary trees, hashing, key encryptions, and filled with the motivation to create a user specific database that will allow him/her to maintain control over his/hers private information, while still being able to prove their ownership over the information and the integrity of that information, I decided to play a little with different Solidity codes. The idea was to use mapping as the mean of creating pairs of leaves and root.

 

Each leaf is hashed with the previous root to produce the new root of the tree

Each root is the hashed of all of the chain that lies bellow its level, plus the new leaf added. This way, each attached leaf if linked and chained with the rest.

pragma solidity ^0.4.6;

contract Data{
    
    struct tree{
        bytes32 root;
        mapping(bytes32=>bytes32) leafAndRoot;
    }

    bytes32 public empty;                                           // Hard codded         
    
    mapping (address=>tree) public users;
    
    function newUser(){                                             // To do - Modifer "onlyNewUser" 
        users[msg.sender];
    }
    
    function addData(
            uint256 _data,              // To do - serialize data/non empty
            address _user)
            returns (bool success){  
        
        var leaf    = keccak256(_data);   // Hashing the input
        var oldRoot = getUserRoot(_user);
        var newRoot = hashTheTwo(leaf, oldRoot);
        
        users[_user].leafAndRoot[leaf] = newRoot;
        users[_user].root = newRoot;

        return true;
    }
    
    function getRoot(
            uint256 _leafData,      // The input is in plain uint256 and hashed format to allow for future UI to be devloped
            address _user)
            constant 
            returns (bytes32 root){ // The root of specific leaf
        
        var leaf = keccak256(_leafData);                                            // Hashing the input
        return users[_user].leafAndRoot[leaf];
    }
    
    function getUserRoot(
                address _user)
                constant
                returns (bytes32 root){ // The higest (last) root      
        return users[_user].root;
    }

    function hashTheTwo
                (bytes32 _a, // To do - serialize data/non empty
                bytes32 _b)  // To do - serialize data/non empty
                constant
                returns (bytes32 hashed){         
        return keccak256(_a, _b);
    }
    
    function checkDataIntegrity
            (uint256[] _data, // To do - serialize data/non empty
            address _user)
            constant         // Run localy
            returns (bool complete){ 
         
         

        var oldRoot = empty;                         // Hard codded                        
        for (uint i = 0; i < _data.length; i++) {    // Reconstructing the tree     
            var data = keccak256(_data[i]);          // Hashing the input
            var root = hashTheTwo(data, oldRoot);
            
            if(root == getRoot(_data[i], _user)){         
                oldRoot = root;
                continue;
            }else{
                return false;
            }
        }        

        if (oldRoot == getUserRoot(_user)){
            return true;
        }else{
            return false;
        }
    }
}

For each new user, a new struct object is created containing two parts, The latest root in the tree, and the tree itself. The tree maps from bytes32 (the data/leaf) to the bytes32 of the root. That way a user can look up for a specific information and, if the root is valid, attest that the said information is indeed present in the database, while others cannot tell what the real information is just by looking at the blockchain.

Currently, due to input limitations in solidity, the easiest way to input and parse and the array is by using u/int array. Future implementation might include bytes32[] array or even direct string array as input.

All the input values are hashed to get a uniform 32 bytes result and to increase privacy.

function hashTheTwo(
        bytes32 _a,
        bytes32 _b)
        constant
        returns (bytes32){         // To do - serialize data/non empty
    return keccak256(_a, _b);
}

The data is then hashed together with the highest existing root to receive the new root of the tree (If the tree is empty, meaning no root exist yet, the first leaf is hashed with empty bytes32 variable).

The new root is then stored in a dedicated variable to allow adding extra information without manually looking for the latest existing root.

function addData
        (uint256 _data,
        address _user)
        returns (bool){                 // To do - serialize data/non empty
    
    var leaf    = keccak256(_data);     // Hashing the input
    var oldRoot = getUserRoot(_user);
    var newRoot = hashTheTwo(leaf, oldRoot);

    users[_user].leafAndRoot[leaf] = newRoot;
    users[_user].root = newRoot;

    return true;
}

When trying to prove the authenticity of a single entry, it’s enough to just check for the existence of a (none empty) root that corresponds to that specific piece of information.

function getRoot(
            uint256 _leafData,
            address _user)
            constant
            returns (bytes32){ // The root of specific leaf

    var leaf = keccak256(_leafData);                                            // Hashing the input
    return users[_user].leafAndRoot[leaf];
}

// Can also be rewtiren to give bool result

function isExist(
            uint256 _leafData,
            address _user)
            constant
            returns (bool exist){
            
    var leaf = keccak256(_leafData);                                            // Hashing the input
    if(getRoot(_leafData, _user) != 0x00){
        return true;
    }else{
        return false;
    }            
}

Proving the existence of the entire database is done by providing all the pieces in their proper order and reconstructing the finale root. If the results match the one stored on the blockchain, that means that the owner of that data array has a complete copy of that array.

function checkDataIntegrity(
            uint256[] _data,
            address _user)
            constant
            returns (bool){ 
     
     // To do - serialize data/non empty
     // Run localy

    var oldRoot = empty;    // Hard codded                        
    for (uint i = 0; i < _data.length; i++) {

        var data = keccak256(_data[i]);         // Hashing the input
        var root = hashTheTwo(data, oldRoot);

        if(root == getRoot(_data[i], _user)){   // Reconstructing the tree 
            oldRoot = root;
            continue;
        }else{
            return false;
        }
    }        

    if (oldRoot == getUserRoot(_user)){
        return true;
    }else{
        return false;
    }
}

The complete code plus test file can be found on my github page

Contract: test 01
    The first stage is Deploying Data
      ✓ Deploys the Data contract
      ✓ Register account 0 user (69ms)
    Adds three datas to account 0 user tree
      ✓ get account 0 user root - should be undefined (79ms)
      ✓ Adds the first data 1 (108ms)
      ✓ Adds the second data 2 (86ms)
      ✓ Adds the third data 5 (79ms)
    Check data integrity
      ✓ Pass the complete array [1, 2, 5] - expect true (122ms)
      ✓ Pass the  array [1, 2] - expect false (93ms)
      ✓ Pass the  array [1, 5, 2] - expect false (83ms)


  9 passing (818ms)
    

What can I do with it?

I can use the above system to prove that I’m in control over my own data, that I have the original data and that I maintain a complete copy of my database. Such a system can be combined with other types of encryptions to prove that the data is both belongs to me, complete, and recognized by other authorities.

I prove that I have a my complete medical file, I prove that the said message belongs to me and that it was signed by myself and by the doctor
Ethereum signature validation app

Ethereum signature validation app

Import: This article is for educational purposes only. Don’t attempt to incorporate the codes and methods presented here into working applications and don’t use keys that are associated with your real Bitcoin/Ethereum wallets.

 

The key pair

Key pair (Asymmetric encryption) is one of the building blocks of current blockchain solutions and cryptocurrencies, without it, Bitcoin, Ethereum and other blockchains were not possible.

The idea behind this tool is quite simple: Encrypting information using one key (public key) and decryption it using another (private key).

This short video gives a great introduction to the concept of key pairs as well as an explanation to the mathematical background behind RSA asymmetric encryption

  • Rememebr that both Bitcoin and Ethereum aren’t using RSA encryption. Instead they’re using ECC (Elliptic Curve). The mathematical background is different for the two, yet the main principle is the same.

 

As seen in the video, asymmetric encryption has been around for quite some time and it’s by no mean a unique feature of the blockchain. However, both Bitcoin and Ethereum (and probably many other blockchains) utilize it in a slightly different way. Rather than using the public key to encrypt a message, they’re using the private key to sign a message.

This signed message has some interesting proprieties, but the one thing what makes it really useful in the blockchain context is that the public key can be used to validate to authenticity of the signer.

 

original_msg = "hello"

private_key = "0x010203..."

public_key = "0x0f0e0d..."

signed_message = sign(original_msg, private_key) = "0xaabbcc..."

validate(public_key, original_msg) = True

As you can see, the idea wasn’t necessarily to hide the information (the original message need to be presented in order to validate authenticity of the signer). Instead, we use this method to prove the owner of a specific private key is indeed the one who signed the original message.

In the blockchain sense, Bob can sign the original_msg -the transaction (which is of course publicly available to anyone who have a copy of the blockchain), and by providing his own public key and the signature, everyone can verify that that specific message was indeed signed by Bob.

 

The validator

Originally, I planned to write some basics codes demonstrating the process in Bitcoin and Ethereum, but while studying Ethereum more in depth, I encountered the Solidity ecrecover method that returns the address associated with the signed message, and I immediately sat down to create the Validator, a simple app that uses web3.js to sign a message at the client side, and then uses smart contract to get the address of the signer (btw, the ability to display the address of the one who signed the message hints at another interesting property which I might go deeper into in another post).

The source code can be found here:
https://github.com/Shultzi/validator

Step by step

The process was very simple, first I created the smart contract:

contract Validator{
    
    function constVerify(bytes32 r, bytes32 s, uint8 v, bytes32 hash) constant returns(address) {
        return ecrecover(hash, v, r, s);    
    
    function verify(bytes32 r, bytes32 s, uint8 v, bytes32 hash) returns(address) {
        return ecrecover(hash, v, r, s);
    } 
}

The contract Validator contains two functions but both are basically doing the same. The only different is that the first one is constant, that means no transaction is sent to the Ethereum network (caution! request might still be sent to a remote node if you don’t run a local Ethereum node!). This function will instantly return the address of the one who signed the original message. The other function is not a constant function, that means that a transaction will be sent to the Ethereum blockchain and the returned result will be verified by all of the users (consider the implications in terms of privacy!) the result however will not be immediately displayed to the end user – instead, in my app the user will receive the hash of the transaction. The user can then look it up on the blockchain.

The ecrecover function itself is very simple to use, all you need is the hash of the original message (hash) and the signed message (r, s, v).

The original message is hashed to ensure that uniform size, so that regardless to the size of the original message, we’ll always have a hash variable of exactly 32 bytes.

The r, s, v are all parameters of the signed message. The signed message itself (as you might already saw in the above video) is actually a combination of 3 variables.

full_sign = 0x042995e2dd996f8d234be59a623f3a2b02d3fb91187f48eaf563723b342225cc16599133550d998c880ecb1a8d29f47216f0397e30e415b95d92490f3b4ca6201b

r = 042995e2dd996f8d234be59a623f3a2b02d3fb91187f48eaf563723b342225cc //32 bytes

s = 16599133550d998c880ecb1a8d29f47216f0397e30e415b95d92490f3b4ca620 //32 bytes

v = 1b //uint8 (1 byte)

The signed message can be received using the web3.js library. I used meteor (based on nodejs) to launch my application.

Once it was launched, I declared web3 object like so:

if(typeof web3 !== 'undefined'){
  web3 = new Web3(web3.currentProvider);
}else{
	web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8080"));
};

The web3 is connected to metamask via chrome extension, but you can of course use your own preferred client like geth, parity or testrpc.

Once web3 is declared, getting the full signature is a very simple thing to do:

web3.eth.sign(web3.eth.accounts[0], web3.sha3(msgToSign.value), function(err, res){signedmsg = res;});

This is the full signature. r + s + v. We’ll need to break it into their component. Just remember that:

  • The first 32 bytes are the r value
  • The second 32 bytes are the s value
  • The last byte is v value (uint8)

You can read more about signature structure here

Breaking the signature into its r, s, v values is a fairly easy process that can be done with the following JavaScript code.

r = "0x" + signedMsg.value.slice(2, 66); //Treated as hex
s = "0x" + signedMsg.value.slice(66, 130); //treated as hex
v = new Buffer(signedMsg.value.slice(130, 132), "hex"); // we care for the numeric value. The Ethereum function expects uint8 and not hex.
v = v[0].valueOf();
h = web3.sha3(originalMsg.value); //we hash the original message to keep it as 32 bytes, regardless to the input size.

Now the only thing that is remained is to send these values along with the original message to smart contract, and get the result back.

Validator.verify(r, s, v, h, function(err,res){         		
    Template.address.set("The transaction id is: " + res);
});

Validator.constVerify(r, s, v, h, function(err,res){
    Template.address.set("The signer address: " + res);
});

The final result

http://nobelgoeshere.com/ (The site isn’t secured. Don’t sign anything of value!)

Signing and validating message in ethereum

 

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