Javascript API 2

In the previous tutorial we used some of the basic javascript functions available within the client to passively retrieve information from the locally stored blockchain, in this tutorials we are going to examine the ways you can amend the blockchains state.

There is only one way to interact with the blockchain and that is by sending transactions. There are three main types that are important: transactions that send value, transactions that create contracts, and transactions that send data to those contracts.

Once again I have created a html template, with space for you to fill in the required javascript:


<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>JSAPI_1.html</title>
		<a href="index.html">Back to Contents</a>
		<script type="text/javascript">
		
		//contract source code

		//contract abi object
		
		//function for a simple transaction to transfer ether
		
		//function to create a new contract from our source code
		
		//function to send transaction using attributes from the HTML input boxes
		
		</script>
	</head>
	<body>
		<div>
			<div>
				<h3>Transact Example</h3>
			</div>
			<div>
				<input id="recipient" type="text" placeholder="To">
				<input id="value" type="text" placeholder="Value in Wei">
			</div>
			<div>
				<button onclick="sendEther();">Send Ether</button>
			</div>
			<div>
				<h3>Create a contract</h3>
			</div>
			<div>
				<button onclick="createSolidityContract();">Create Solidity Coin Contract</button>
			</div>
			<div>
				<h3>Send some coins</h3>
			</div>
			<div>
				<input id="receiverAddress" class="form-control" type="text" placeholder="Receiver address"></input><br>
				<input id="amount" class="form-control" type="text" placeholder="Amount"></input><br>
			</div>
			<button onclick="dataTransaction();">Send transaction</button>
		</div>
		<div>
			Put in addresses prefixed with '0x' and hit 'Send transaction'
		</div>
	</body>
</html>

Copy-paste the above into a html file, save it somewhere in your workspace and open it up in Alethzero. You should see something like this:

This form is setup for the three types of transactions listed above, and we are going to add the code that will allow it to work piece by piece.

The Javascript function we will be using throughout is web3.eth.transact() this function takes a JSON object as its argument and the JSON object has many possible attributes.

The only two attributes we need to concern ourselves with in our first transaction is are “to” and “value” which are the recipient address and the amount of ether we wish to send (this is calculated in its base unit ‘wei’). Transact is an asynchronous function and its callback returns various pieces of information (the point of which I will explain later).

Copy the below into our html template and open the web page in Alethzero:

function sendEther() {
web3.eth.transact({to: document.querySelector('#recipient').value ,value: document.querySelector('#value').value});
};

It should be fairly easy to see how this works, the transact function is being passed a JSON object with attributes ‘to’ and ‘value’ whose values are pulled from our form input. We could also include the attributes gas and gasPrice, but these default to the total amount of ether available and the current mean price for gas on the network, which is sufficient for this example.

Copy and paste any address into the to box and as many wei as you wish to send in the amount (remember there are 10^18 wei in an ether). Hit transact. Hitting this button calls the function ‘sendEther’ which instructs the client to send a transaction to the network.

Screen Shot 2015-02-27 at 11.38.06 (2)

First you will see a warning pop up from Alethzero informing you that the web page has requested the client send a transaction. Click approve and you should see a transaction appear in the ‘pending’ pane if this has worked correctly. Make sure you mine a block to commit it to the chain and check the balances update correctly.

The next transaction we will perform is going to pass EVM code to the blockchain, without a specified recipient, in order to create a new contract.

Before we do this we need some EVM code to pass to the transaction. Fortunately our JavaScript API is capable of compiling solidity to byte code to be passed in an array. Firstly we will create a Javascript object containing code for our Solidity metaCoin. Add this to your html page:

var soliditySource = "contract metaCoin {\n"+
" mapping (address => uint) balances;\n" +
" function metaCoin() {\n" +
" balances[msg.sender] = 10000;\n" +
" }\n" +
" function sendCoin(address receiver, uint amount) returns(bool successful) {\n" +
" if (balances[msg.sender] < amount) return false;\n" +
" balances[msg.sender] -= amount;\n" +
" balances[receiver] += amount;\n" +
" return true;\n" +
" }\n" +
"}";

We have come across this code before and previously uploaded it to the blockchain using Alethzero’s transact pane. This time we will compile it in the browser and upload it as bytecode. The function for compiling from solidity is web3.eth.solidity() and when passed solidity code produces EVM bytecode.

You can try this now. Copy and paste the above into your html template. Reload the page in AZ and then go to the JavaScript console and type:

web3.eth.solidity(soliditySource)

This should return:

"60056011565b60a28060376000396000f35b6127106000600033600160a060020a0316815260200190815260200160002081905550560060003560e060020a9004806390b98a1114601557005b60216004356024356027565b60006000f35b806000600033600160a060020a031681526020019081526020016000205410604d576051565b609e565b806000600033600160a060020a03168152602001908152602001600020908154039081905550806000600084600160a060020a031681526020019081526020016000209081540190819055505b505056"

Now we have bytecode we can pass it as a paramenter in the transact function using the “code:” prefix like this:

web3.eth.transact({code: '0x60056011565b60ae8060326000396000f35b612710600033600160a060020a0316600052602052604060002081905550560060e060020a6000350480637bb98a6814601e578063d0679d3414602a57005b6024603d565b60006000f35b60366004356024356042565b60006000f35b5b600081565b80600033600160a060020a0316600052602052604060002054106063576067565b60aa565b80600033600160a060020a0316600052602052604060002090815403908190555080600083600160a060020a031660005260205260406000209081540190819055505b505056'})

This uploads our contract to the blockchain in the exact same way as inputting solidity into the transact pane. The above would create a callback that would return the address of the contract created.

Copy and paste the below into your html document:

function createSolidityContract() {
web3.eth.transact({code: web3.eth.solidity(soliditySource)});
};

This allows us to create a contract with one click from the browser window. You can use this method to compile and deploy any contract you want through the browser. You can also use web3.eth.serpent() to compile serpent code in the same way.

Try this now by opening up your html page in Alethzero and clicking on the ‘create solidity contract’ button – it will cause a pop-up warning that you are sending a transaction with zero wei to the network – approve it and you should see it appear in the pending pane.

In our previous examples we showed how it was possible to interact with contracts using the transact pane in Alethzero by building a data array to pass to contracts. The Javascript API abstracts this process and allows you to call functions directly by creating a model of the contracts functions within the browser.

Firstly, we are going to model the contracts functions by defining an array of JSON objects corresponding to the functions our contract has. Each object represents a function of the contract and is made up of very specific attribute-value pairs. The first attribute is unsurprisingly ‘name’ and its value is case sensitive and must be of the format nameOfFunction(argumentType1, argumentType2,…) for our contract above it should look like this:

"name": "sendCoin(address,uint256)",

The Second attribute is ‘type’ – in this case the type is ‘function’ I will cover other types in a later tutorial:

"type": "function",

finally we need to define the inputs of the function as an array of objects (both of which have attributes ‘name’ and ‘type’):

"inputs": [
{
"name": "receiver",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
]

If our function returned a value we would also define “outputs” so that our javascript would know how to handle the data array passed back to the browser by the callback.

Putting this all together to create a javascript object describing our contract:

var contractDesc = [{
"name": "sendCoin(address,uint256)",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address"
},
{
"name": "value",
"type": "uint256"
}
]
}];

Make careful note of the curly brackets indicating objects, and the square brackets indicating arrays. Now we have a description of our contracts function and the arguments it takes we can create a ‘contract’ object using web3.eth.contract() a function which takes two arguments, the first is the address of the contract as a 160bit hex string, the second is the contract description:

contract = web3.eth.contract(address, contractDesc);

Lets go back and amend our ‘createSolidityContract()’ function to also create this object:

var contractDesc = [{
"name": "sendCoin(address,uint256)",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address"
},
{
"name": "value",
"type": "uint256"
}
]
}];

...

function createSolidityContract() {
var address = web3.eth.transact({code: web3.eth.solidity(soliditySource)});
contract = web3.eth.contract(address, contractDesc);
};

Here we have made a couple of important changes, firstly we have declared a new variable ‘address’ which is the value returned by the transact function which creates our contract. Secondly we declare a new global object ‘contract’ which is created when we pass the contract description object along with our contracts address to the web3.eth.contract function.

With our new contract object we can easily interact with the contract on the blockchain simply by calling the functions we have defined above. For example:

contract.sendCoin('0x878965387afd76fd008e7668','500')

Will send a transaction instructing the contract to send 500 coins to the account ‘0x878965387afd76fd008e7668’. We can easily setup a JS function which takes these arguments from our html form and passes them to the contract:

function dataTransaction() {
var receiverAddress = document.querySelector('#receiverAddress').value;
var amount = document.querySelector('#amount').value;
contract.send(receiverAddress, amount);
};

When executed this generates a larger pop-up window warning you that the client has received a request from the front end to send a transaction which includes data. It also clearly warns that the client does not understand what effect this data might have on the contracts state and that it might be far more profound than just a transfer of ether or some gas costs. You can safely ignore this message for now but in later tutorials I will show how you can generate documentation for your contract that will replace this warning with something more informative.

Check the state of your contract once a new block has been mined. You should see the changes to the storage registering inside it.

This completes the tutorial on transactions, in the next JS API tutorial we will cover using ‘accessor’ functions, making calls to functions and sending other general commands to the client.

One thought on “Javascript API 2

  1. Hi
    in the last example shouldn’t it be: “contract.sendCoin(receiverAddress, amount);”, instead of “contract.send(receiverAddress, amount);”
    also how can I tell the javascript when I call “contract.send(receiverAddress, amount);” to send a certain amount of ether with the transaction?
    I am having a contarct which has a function like: “contract.deposit()” and it takes no arguments, instead it takes the amount from the value of the transaction. How do I realize that with a javascript call?

    Btw, great tutorial, thanks!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s