Ethereum provides the solc compiler, which provides a command-line interface to compile .sol files. Visit http://solidity.readthedocs.io/en/develop/installing-solidity.html#binary-packages to find instructions to install it and visit https://Solidity.readthedocs.io/en/develop/using-the-compiler.html to find instructions on how to use it. We won't be using the solc compiler directly; instead, we will be using solcjs and Solidity browser. Solcjs allows us to compile Solidity programmatically in Node.js, whereas browser Solidity is an IDE, which is suitable for small contracts.
For now, let's just compile the preceding contract using a browser Solidity provided by Ethereum. Learn more about it at https://Ethereum.github.io/browser-Solidity/. You can also download this browser Solidity source code and use it offline. Visit https://github.com/Ethereum/browser-Solidity/tree/gh-pages to download it.
A major advantage of using this browser Solidity is that it provides an editor and also generates code to deploy the contract.
In the editor, copy and paste the preceding contract code. You will see that it compiles and gives you the web3.js code to deploy it using the geth interactive console.
You will get this output:
var proofContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"fileHash","type":"string"}],"name":"get","outputs":[{"name":"timestamp","type":"uint256"},{"name":"owner","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"owner","type":"string"},{"name":"fileHash","type":"string"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"status","type":"bool"},{"indexed":false,"name":"timestamp","type":"uint256"},{"indexed":false,"name":"owner","type":"string"},{"indexed":false,"name":"fileHash","type":"string"}],"name":"logFileAddedStatus","type":"event"}]);
var proof = proofContract.new(
{
from: web3.eth.accounts[0],
data: '60606040526......,
gas: 4700000
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
data represents the compiled version of the contract (bytecode) that the EVM understands. The source code is first converted into opcode, and then opcode are converted into bytecode. Each opcode has gas associated with it.
The first argument to the web3.eth.contract is the ABI definition. The ABI definition is used when creating transactions, as it contains the prototype of all the methods.
Now run geth in the developer mode with the mining enabled. To do this, run the following command:
geth --dev --mine
Now open another command-line window and in that, enter this command to open geth's interactive JavaScript console:
geth attach
This should connect the JS console to the geth instance running in the other window.
On the right-hand side panel of the browser Solidity, copy everything that's there in the web3 deploy textarea and paste it in the interactive console. Now press Enter. You will first get the transaction hash, and after waiting for some time, you will get the contract address after the transaction is mined. The transaction hash is the hash of the transaction, which is unique for every transaction. Every deployed contract has a unique contract address to identity the contract in the blockchain.
The contract address is deterministically computed from the address of its creator (the from address) and the number of transactions the creator has sent (the transaction nonce). These two are RLP-encoded and then hashed using the keccak-256 hashing algorithm. We will learn more about the transaction nonce later. You can learn more about RLP at https://github.com/Ethereum/wiki/wiki/RLP.
Now let's store the file details and retrieve them.
Place this code to broadcast a transaction to store a file's details:
var contract_obj = proofContract.at("0x9220c8ec6489a4298b06c2183cf04fb7e8fbd6d4");
contract_obj.set.sendTransaction("Owner Name", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", {
from: web3.eth.accounts[0],
}, function(error, transactionHash){
if (!err)
console.log(transactionHash);
})
Here, replace the contract address with the contract address you got. The first argument of the proofContract.at method is the contract address. Here, we didn't provide the gas, in which case, it's automatically calculated.
Now let's find the file's details. Run this code in order to find the file's details:
contract_obj.get.call("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
You will get this output:
[1477591434, "Owner Name"]
The call method is used to call a contract's method on EVM with the current state. It doesn't broadcast a transaction. To read data, we don't need to broadcast because we will have our own copy of the blockchain.
We will learn more about web3.js in the coming chapters.