banner



Where To Put Code For Smart Contracts?

Originally published at consensys.github.io/developers (where some of the lawmaking formatting might be easier to read).

Some people say Ethereum is too logic-heavy and difficult to apply, but here's a write-up to give you a feel for building smart contracts and applications with information technology. Tools, wallets, applications and the ecosystem are still in development and it'll get easier!

  • Part I is an overview of key terms and discusses Ethereum Clients and Smart Contract Languages.
  • Role 2 discusses overall workflow and some current DApp Frameworks and Tools and
  • Role III is the Programming Part, a quick walkthrough of writing tests and building a DApp for a smart contract using Truffle.

Part I. Intro

If you're new to all this cryptocurrency stuff, including Bitcoin and how it works, check out the beginning couple chapters of Andreas Antonopoulos' Bitcoin Volume to dip your toe in the water. Then head over to the Ethereum Whitepaper.

If you starting time getting into some murky sections and would rather build something to get familiar kickoff, then just read on. Yous don't take to understand all the crypto economic computer science to start building, and a lot of that paper is nearly Ethereum's improvements over Bitcoin'south compages.

Starter Tutorials

The official place to start is ethereum.org which has a starter tutorial and follow-upwards token and crowdsale tutorials. There's as well the official Solidity docs. Some other good place to get-go with smart contracts (where I started) is dappsForBeginners, although it might be outdated.

The goal of this write-up is to complement those tutorials and innovate some helpful dev tools that make starting out with Ethereum, smart contracts and building DApps (decentralized apps) easier. And to endeavor to explain the overall flow of what's going on. This is from my (still-noob) perspective and with much assist from the absurd developers at ConsenSys.

Bones Concepts

Information technology'd be expert to know some of these terms:

Public Fundamental Cryptography. Alice has a public primal and private key. She can employ her individual key to create a digital signature, and Bob can use Alice's public key to verify that a signature is really from Alice'due south individual key, i.e., actually from Alice. When you create an Ethereum or Bitcoin wallet the long '0xdf…5f' address is a public key and the private key is stored somewhere. A Bitcoin wallet service like Coinbase stores your wallet's complementary individual primal for yous, or y'all tin can store it yourself. If you lose your private fundamental for a wallet with real funds you'll lose all your funds forever, so it'southward good to back up your keys. It hurts to larn this the hard mode! I've washed it.

Peer-to-Peer Networking. Like BitTorrent, all Ethereum nodes are peers in a distributed network, at that place's no centralized server. [In the future, there'll be hybrid semi-centralized services for Ethereum as a convenience to users and developers, more on that afterwards.]

Blockchain. Like a global ledger or simple database of all transactions, the unabridged history of all transactions on the network.

Ethereum Virtual Machine. So you can write more than powerful programs than on pinnacle of Bitcoin. Information technology refers to the blockchain, what executes smart contracts, everything.

Node. Using this to mean yous can run a node and through it read and write to the Ethereum blockchain, i.e., apply the Ethereum Virtual Machine. A total node has to download the entire blockchain. Calorie-free nodes are possible but in the works.

Miner. A node on the network that mines, i.e., works to process blocks on the blockchain. You lot can meet a partial listing of live Ethereum miners here: stats.ethdev.com.

Proof of Piece of work. Miners compete to do some math problem. The first one to solve the problem (the next block on the Blockchain) wins a advantage: some ether. Every node then updates to that new block. Every miner wants to win the next new cake and so are incentivized to keep up to appointment and have the one true blockchain everybody else has, and so the network e'er achieves consensus. [Notation: Ethereum is planning to motion to a Proof of Pale system without miners somewhen, merely that'southward across noob scope.]

Ether. Or ETH for short. It's a real digital currency you can buy and use! Here's a chart from one of several exchanges for it. At the time of writing, 1 ETH is worth most 65 cents in USD.

Gas. Running and storing things on Ethereum costs pocket-size amounts of ether. Keeps things efficient.

DApp. Decentralized App, what applications using smart contracts are chosen in the Ethereum community. The goal of a DApp is (well, should be) to have a overnice UI to your smart contracts plus any actress niceties similar IPFS (a neat mode to store and serve stuff in a decentralized network, non made by Ethereum but a kindred spirit). While DApps can be run from a key server if that server can talk to an Ethereum node, they tin too exist run locally on top of any Ethereum node peer. [Take a minute: unlike normal webapps, DApps may not exist served from a server. They may use the blockchain to submit transactions and retrieve data (important data!) rather than a primal database. Instead of a typical user login system, users may be represented by a wallet addresses and go along any user information local. Many things can be architected differently from the current spider web.]

For some other noob angle on some of the concepts above here's a good read: Just Enough Bitcoin for Ethereum.

Ethereum Clients, Smart Contract Languages

You don't have to run an Ethereum node to write and deploy smart contracts. See Browser-based IDEs and APIs beneath. But if yous're learning, run an Ethereum node, it's skillful to get to know every bit a basic component and not difficult to prepare up.

Clients for Running an Ethereum Node

Ethereum has several dissimilar client implementations (meaning ways to run a node to interact with the Ethereum network) including C++, Become, Python, Java, Haskell, etc. Why? Different strokes for dissimilar folks (similar how the Haskell one is supposedly mathematically verifiable), and it improves the security and ecosystem of Ethereum to have so many. There's also a gui-based customer in development, AlethZero.

At the time of writing, I've been using geth, the Go language i (get-ethereum) and on other days a tool called testrpc that uses the Python client, pyethereum. [Update: A new pop tool nosotros use in lieu of testrpc at present is ethersim that uses ethereumJS. EthereumJS is a JavaScript client that doesn't support real blockchain mining, so information technology'southward not a full client similar the others listed above, but mining can be false for testing and evolution purposes.] The afterwards examples will involve those tools.

[Sidebar: I've likewise tried the C++ one and yet use its ethminer component for mining forth with geth as the node, so unlike pieces can piece of work together. Sidebar on Mining: Mining tin be fun, sort of like having a houseplant yous tend to, and another way to acquire about the ecosystem… fifty-fifty if the price of ETH right now is not worth the local electricity costs of mining, that may change. Particularly if everyone starts edifice absurd DApps and Ethereum becomes more popular.]

Interactive Console. Once you have a node using one of the clients, you lot can sync with the blockchain, create wallets and send and receive real ether. I way to practice that with geth is through the JavaScript panel. Some other fashion is via JSON RPC (remote process calls) using a command like cURL for getting stuff via URLs. Nevertheless the goal of this commodity is to walk you through a DApp development scenario so allow'south but move on. Just these tools are good to remember for debugging, configuring nodes and using a wallet via command line.

Running a node on a test network. If you lot install a customer like geth and run information technology on the live network, it volition take a while to download the entire blockchain and sync with the network. (You can check that information technology'southward synced by seeing that you have the latest block which is listed at the pinnacle of stats.ethdev.com and comparing that number to the block number output by your client node'south logs.)

Nevertheless, to run smart contracts on the alive network you'd have to coughing upward some real ether. Instead, there are ways to run clients on a local testnet for costless. They won't download the full blockchain and will create a private instance of the Ethereum network with its own blockchain, so are faster to use for evolution.

testrpc. You can run a test network using geth, or another fast way of getting a testnet running is using testrpc. Testrpc will create a agglomeration of pre-funded accounts for you that will exist listed when it starts upward. It's is likewise super fast, and then easier to develop and test with. You can get-go with testrpc, and then when your contracts are in proficient shape, movement to geth on a testnet, which can exist started by specifying a networkid like: geth — networkid "12345". Here's the testrpc repo but I'll review everything you need to install again in the tutorial function later. [Update: The programmer of testrpc is now focusing on ethersim as a replacement for testrpc and I'll update this tutorial eventually to use ethersim too. You tin can start using it now in if you'd like. Ethersim is based on ethereumJS and simulates mining for dev purposes and is very fast.]

Let's talk most programming languages next, then nosotros can dive into really coding stuff.

Programming Languages for Smart Contracts

Only use Solidity. To write smart contracts there are a few different languages: Solidity, which is similar JavaScript and has .sol as a file extension, Serpent, Python-similar with extension .se, and a 3rd, LLL, based on Lisp. Serpent was popular a while back but Solidity is the most popular right at present and more robust, so just use Solidity. You adopt Python? Use Solidity.

solc Compiler. After writing a contract in Solidity, use solc to compile it. It'due south from the C++ libraries (different implementations complementing each other again) which tin can be installed hither. [If yous don't desire to install solc you can also merely apply a browser-based compiler like the Solidity real-time compiler or Cosmo, but the programming part later on will assume you have solc installed.]

[Annotation: Ethereum's libraries are undergoing active development and sometimes things exit of sync with new versions. Brand sure you take the latest dev version, or a stable version. Enquire in ane of the Ethereum Gitter's on Github or forums.ethereum.org what version people are using if things that used to work end working.]

web3.js API. One time a Solidity contract is compiled with solc and sent to the network, y'all can telephone call information technology using the Ethereum web3.js JavaScript API and build web apps that collaborate with contracts. (No need to install this yet, read upward on DApp Frameworks below first.)

Those are the basic Ethereum tools for coding smart contracts and interacting with them to build DApps.

Part 2. DApp Frameworks, Tools and Workflow

DApp-building Frameworks

You can do all these steps with just the tools mentioned above, only some helpful devs have created DApp frameworks to make development easier.

Truffle and Embark. The one that got me started is Truffle. (Before Truffle I watched a group of smart educatee interns terminal summer code stuff for a sleepless hackathon (albeit with terrific results) and shrank back in fear. Then Truffle came along and did a lot of the nitty gritty stuff for you, so you can start writing-compiling-deploying-testing-building DApps right away.) Another very similar framework for building and testing DApps is Embark. Betwixt those two, I've only used Truffle, simply there are very successful DApp devs in both camps. [Update: Another good dapp-building frameworks are Dapple and Populus. Dapple too just got a dev grant to be improved.]

Falling star. Another stack a lot of DApp devs use include web3.js + Falling star which is a general webapp framework (The ethereum-meteor-wallet repo has a good starter case, and SilentCiero is building a lot of Shooting star integrations with web3.js and DApp boilerplates). I've downloaded and run cool DApps that do things this way. There'll be some interesting discussion of all of these tools and best practices for building DApps at Ethereum's ÐΞVCON1 conference November. ix–13th (which will too be streamed or on YouTube).

APIs. BlockApps.cyberspace is creating a RESTful API for DApps based on a Haskell node they run as a centralized service to relieve you the trouble of running a local Ethereum node. This departs from the completely decentralized model of DApps but is useful when running an Ethereum node locally isn't realistic. For example if you desire to serve your DApp to users who won't be running local nodes either and reach a wider audience with just a web browser or mobile device. BlockApps has a control line tool called bloc in the works that can be used after creating a programmer account with them.

If users take to run a local Ethereum node to use DApps isn't that a dealbreaker? Like BlockApps there are a range of tools in development then this won't exist. Metamask lets you run Ethereum stuff in a browser without a node, Ethereum's AlethZero or AlethOne are easier-to-use GUI clients being adult and a LightWallet ConsenSys is building are ways to make interacting with DApps more than painless. Low-cal (SPV) nodes and sharding are also in the works or planned. It's a P2P ecosystem only tin can involve hybrid architectures.

Smart Contract IDEs

IDEs. There's a Mix IDE for writing contracts put out by Ethereum. Oasis't tried it only will presently.

Browser-based IDEs. The Solidity real-fourth dimension compiler and Cosmo are both a fast manner to get started compiling your smart contracts right away in a browser. You lot tin even indicate your local node at these hosted instances by opening up a port (you should trust the site and not accept your life savings in ether on your local node for that! See the Cosmo UI for instructions on how to do this with geth). Simply once your contract is working ok it's nice to apply a framework for adding a UI and packaging it all up as a DApp, which is what Truffle does and will exist explained in the programming part later.

Some other powerful enterprise-y browser IDE is in the works past Ether.Camp. Their IDE comes with a sandbox test network with an car-generated GUI for testing (instead of writing tests manually as shown in the tutorial later) as well as a sandbox transaction explorer at exam.ether.camp. When yous're ready to deploy your contract for semi-real, using their testnet can be a practiced way to confirm your smart contract's working as expected on a closer-to-real testbed. The same explorer for the live Ethereum network is at frontier.ether.campsite and it shows details near every transaction always. Ether.Camp's IDE is invite-only for eager republic of guinea pigs at time of writing but volition be launched soon.

Sample Contracts and DApps. Search Github for DApp repos and .sol files to see what cool stuff people exercise and how. A big list of DApps with repos is as well here: dapps.ethercasts.com, although some of the listing's details are a lilliputian out of date. Ether.fund/contracts too has some examples of Solidity and Serpent contracts people have written, simply not sure if these have been tested or verified for correctness. There'll be a whole day of DApp presentations Thursday, November. 12th at ÐΞVCON1.

Workflow for Deploying Smart Contracts

The workflow is:

  1. Start an Ethereum node (east.grand. geth or testrpc or ethersim)
  2. Compile your Solidity smart contract using solc => get back the binary
  3. Deploy your compiled contract to the network. (This step costs ether and signs the contract using your node's default wallet address, or you tin specify another address.) => go dorsum the contract's blockchain accost and ABI (a JSON-ified representation of your compiled contract's variables, events and methods that y'all tin call)
  4. Phone call stuff in the contract using web3.js's JavaScript API to interact with it (This step may cost ether depending on the blazon of invocation.)

This workflow is depicted in greater detail in the diagram beneath:

Yous could build a DApp that provides a UI for users to deploy a contract and then use information technology (Steps 1 or four). Or your DApp could assume the contract's already been deployed (common) and commencement the UI flow from there (Step vi).

Part Three. The Programming Part, Finally

Testing in Truffle

Truffle is swell for test-driven development of smart contracts which is highly recommended to maintain sanity when you're starting to learn how things piece of work. It'south also useful as a way to learn to write promises in JavaScript, i.eastward., deferred and asynchronous callbacks. Promises are like "do this, then when that comes back, do that, and when that comes back, practise this other thing…and don't go along us waiting while all that'southward going on, ok?" Truffle uses a JS promises framework chosen Pudding on top of web3.js (and so it installs web3.js for you lot too).

Transaction times. Promises are extremely useful for DApps because transactions need to exist mined into the blockchain (takes 12–15 seconds in Ethereum). Fifty-fifty if they don't seem to take that long on a test network it may take longer on the live network, or to find out information technology didn't happen (e.one thousand. your transaction could have ran out of gas, or was mined into a block that's been orphaned).

And then permit'due south copy a simple smart contract and write a test for it.

Using Truffle

Brand sure you take 1. solc installed and 2. testrpc. (For testrpc you'll need Python and pip. If y'all're new to Python, to install it you may also need to use a virtualenv, a way to proceed python libraries carve up on a single computer.)

Install 3. Truffle (You can do this using NodeJS's npm: npm install -g truffle, the -1000 may crave sudo). To verify it installed, blazon truffle list in a console window to list all truffle commands. Then create a new projection directory (I'm naming my new directory 'briefing'), change into information technology, and do truffle init. This will create this directory construction:

At present start a client node in a new panel window past running testrpc (or first your geth node):

Dorsum in the first truffle console window, now type truffle deploy. This will deploy the Example contract truffle init created as average. Whatsoever errors letters you may have volition show upwardly in either the testrpc console window or the truffle window.

As you lot're developing you can do truffle compile to make certain your contracts compile (using solc you tin as well run solc YourContract.sol), truffle deploy to compile and deploy it to the network, and truffle test to run your smart contract tests.

Commencement Contract, Start Test

Here'south a Solidity contract for a Conference where registrants can buy tickets, and the organizer tin set a maximum quota of attendees too as provide refunds. All the code presented in this tutorial is in this repo.

          contract Conference {            
address public organizer;
mapping (accost => uint) public registrantsPaid;
uint public numRegistrants;
uint public quota;
// so you lot can log these events
result Eolith(address _from, uint _amount);
event Refund(address _to, uint _amount);
part Conference() { // Constructor
organizer = msg.sender;
quota = 500;
numRegistrants = 0;
}
function buyTicket() public returns (bool success) {
if (numRegistrants >= quota) { return false; } // meet footnote
registrantsPaid[msg.sender] = msg.value;
numRegistrants++;
Deposit(msg.sender, msg.value);
return truthful;
}
function changeQuota(uint newquota) public {
if (msg.sender != organizer) { return; }
quota = newquota;
}
function refundTicket(address recipient, uint amount) public {
if (msg.sender != organizer) { return; }
if (registrantsPaid[recipient] == amount) {
accost myAddress = this;
if (myAddress.balance >= amount) {
recipient.send(amount);
registrantsPaid[recipient] = 0;
numRegistrants--;
Refund(recipient, amount);
}
}
}
office destroy() { // so funds not locked in contract forever
if (msg.sender == organizer) {
suicide(organizer); // send funds to organizer
}
}
}

[Footnote: Currently if the quota is reached, buyTicket() keeps the money in the contract but the heir-apparent won't get a ticket. And so buyTicket() should use 'throw' to revert ticket buyer'due south transaction. I'll update the code and add a test for this before long. (Thank you to F.V. from the comments for catching this.)]

Permit'due south deploy this.

[Note: At time of writing I have solc 0.ane.iii+ (installed via brew), Truffle five.0.two.iii, testrpc v.0.1.eighteen (using a venv) on Mac Bone Ten 10.x.five.]

Deploying the Contract

Add together a new smart contract. After y'all've done truffle init, or in the existing project directory, copy-paste the Briefing contract into contracts/Conference.sol. Then in the file config/app.json, edit the "deploy" array to include "Conference".

Start testrpc. Start testrpc in a separate console window using testrpc if its not already running.

Compile or Deploy. Run truffle compile to see if the contract compiles, or simply do truffle deploy to compile and deploy at once. This will add the deployed contract's accost and ABI(that JSON-ified version of the compiled contract) to the config directory, which truffle test and truffle build will pull in from subsequently.

Errors? Did that compile? Once more, fault messages may evidence up in either the testrpc console or the truffle console.

Redeploy after restarting a node! If you end your testrpc node, recollect to redeploy whatsoever contracts using truffle deploy before trying to use them again. Each time testrpc restarts it's a blank slate.

Analyzing the Contract

Permit'due south starting time with the variables at the acme of the smart contract:

                      address public organizer;
mapping (address => uint) public registrantsPaid;
uint public numRegistrants;
uint public quota;

address. The starting time variable is the wallet address of the organizer. This is fix when the constructor is chosen in role Conference(). A lot of contracts will likewise phone call this the 'owner'.

uint. An unsigned integer. Infinite is of import on the blockchain so go on things as modest equally possible.

public. Means it can be called from outside the contract. A private modifier would mean it can only be chosen from within the contract (or by derived contracts). If you lot're trying to phone call a variable from a web3.js call in a examination brand sure its public.

Mappings or Arrays. Earlier Solidity added support for arrays, mappings like mapping (accost => uint) were used. This could also be written as address registrantsPaid[] but mappings have a smaller footprint. This mapping will be used to store how much each registrant (represented by their wallet address) has paid and so they can go refunds afterwards on.

More on addresses. Your client node (i.east., testrpc or geth in these examples) can have one or more accounts. In testrpc, on startup an array of 10 "Available Addresses" are displayed:

The beginning 1, accounts[0], is used by default for calling transactions if a different 1 is not specified.

Organizer address vs. Contract accost. Your deployed contract will take its own contract address (different from the organizer'due south address) on the blockchain. This address is accessible in a Solidity contract using this, as used within the refundTicket function in the contract: address myAddress = this;

Suicide, a practiced thing in Solidity. Funds sent to the contract are held in the contract itself. In the destroy function higher up funds are finally released to the organizer set up in the constructor. suicide(organizer); does this. Without it, funds can end up locked in the contract forever (somebody on reddit lost some ether this way), so brand sure to include that method if your contract collects funds!

If you desire to simulate another user or counterparty (e.g. simulate a buyer if y'all're a seller), y'all tin can use some other address from the accounts assortment. To buy a ticket every bit a different user, say accounts[ane], use information technology in the from field:

          briefing.buyTicket({
from: accounts[ane], value: some_ticket_price_integer });

Some Function Calls can be Transactions. Role calls that change the state of the contract (modify values, add records, etc.) are transactions and take implicit sender and value. So inside curly braces { from: __, value: __ } can exist specified in a web3.js function call to send funds to a transaction function from a wallet accost. On the Solidity stop, you tin remember these values using msg.sender and msg.value, which are implicity in Solidty transaction functions:

          function buyTicket() public {            
...
registrantsPaid[msg.sender] = msg.value;
...
}

Events. These are totally optional. Deposit and Send in the contract are events that can be logged in the Ethereum Virtual Machine logs. They don't actually do anything, but are adept practice for keeping runway that a transaction has happened.

Okay, let's write a test for this smart contract to make sure information technology works.

Writing a Test

In your projection binder's examination/ directory rename the example.js examination file to conference.js. Alter all instances of "Example" to "Conference".

          contract('Briefing', part(accounts) {
it("should assert truthful", part(done) {
var conference = Briefing.at(Briefing.deployed_address);
assert.isTrue(true);
done(); // stops tests at this point
});
});

On running truffle test from the projection's root directory you should see the test pass. In the test above truffle gets the contract's accost on the blockchain from Conference.deployed_address.

Allow'south write a test to initialize a new Conference and bank check that the initial variables are being fix correctly. Supervene upon the test in conference.js with this one:

          contract('Briefing', function(accounts) {
it("Initial conference settings should friction match", function(washed) {
var conference = Conference.at(Conference.deployed_address);
// same as previous instance up to here
Briefing.new({ from: accounts[0] }).then(
function(conference) {
conference.quota.telephone call().then(
function(quota) {
assert.equal(quota, 500, "Quota doesn't match!");
}).then(function() {
render conference.numRegistrants.telephone call();
}).then( office(num) {
affirm.equal(num, 0, "Registrants should be zero!");
return briefing.organizer.call();
}).and then( role(organizer) {
assert.equal(organizer, accounts[0], "Owner doesn't match!");
done(); // to stop these tests earlier, move this up
}).catch(done);
}).catch(done);
});
});

Constructor. Conference.new({ from: accounts[0] }) instantiates a new Conference by calling the contract's constructor. Since accounts[0] is used by default if no from is specified, so it could have been left out when calling the constructor:

          Conference.new({ from: accounts[0] }); // aforementioned as Conference.new();        

Promises. That'south what those and then and return's higher up are. What'southward going on higher up might beginning to look similar a securely nested role telephone call chain similar:

          conference.numRegistrants.phone call().and so(
function(num) {
affirm.equal(num, 0, "Registrants should be zero!");
briefing.organizer.call().then(
role(organizer) {
assert.equal(organizer, accounts[0], "Doesn't match!");
}).then(
office(...))
}).then(
function(...))
// Because this would soon go hairy...

Promises flatten this to minimize nesting, permit for calls to return asynchronously and help simplify the syntax of writing "on success do this" vs. "on failure exercise that". Web3.js provides callbacks for asynchronous requests (docs) then you don't accept to wait for transactions to consummate to do stuff in the front end-end. (Truffle uses a promises framework wrapper to web3.js called Pudding, based on the framework Bluebird, which also has advanced hope features.)

telephone call. Utilise this to check the values of variables equally in conference.quota.call() or with an argument like phone call(0) to call a mapping and become index 0. Solidity docs say this is a "message phone call" which is i. not mined and then ii. doesn't have to be from an account/wallet (therefore information technology's not signed with an account holder'southward private keys). Transactions on the other paw, are mined, take to exist from an account (i.due east., signed), and are recorded on the blockchain. Modifying any value in a contract is a transaction. Just checking a variable value is not. So don't forget to add phone call() when calling variables! Crazy things can happen. [Besides, if you're trying to call a variable and having bug brand sure its public.] phone call() tin also be used to telephone call functions that are not transactions. If they are meant to be transactions and yous attempt to call() them, they won't execute as transactions on the blockchain.

assert. Standard JS testing assertion (if you type 'asserts' plural past blow truffle will have errors and yous won't know what's going on), see the Chai docs for other types of assertions but affirm.equal is commonly all you need.

Run truffle test over again to brand certain that works for you.

Writing a Examination calling a Contract Function

Let'southward examination that the function that changes the quota works. Inside the contract('Conference', function(accounts) {…}; torso of tests/conference.js stick this boosted exam:

          information technology("Should update quota", office(done) {
var c = Briefing.at(Conference.deployed_address);
Briefing.new({from: accounts[0] }).then(
part(briefing) {
conference.quota.call().then(
function(quota) {
affirm.equal(quota, 500, "Quota doesn't match!");
}).then(
function() {
render conference.changeQuota(300);
}).then(
office(effect) {
panel.log(result);
// printed will be a long hex, the transaction hash
return conference.quota.call();
}).then(
part(quota) {
assert.equal(quota, 300, "New quota is not right!");
done();
}).catch(done);
}).take hold of(done);
});

The new thing is the line that calls the changeQuota function. The console.log is as well useful for debugging to print the outcome in the truffle panel'southward output. Add together a console.log to see if the execution gets to a certain point. Besides make sure the changeQuota function in the Solidity contract is public, or you won't be able to call it:

          part changeQuota(uint newquota)            public            { }        

Writing a Test for a Transaction

Let's telephone call a function that expects funds from a wallet address.

Wei. Ether has a lot of denominations (here'due south a helpful converter) and the i commonly used in contracts is Wei, the smallest. Web3.js provides convenience methods for converting ether to/from Wei, as in web3.toWei(.05, 'ether'). JavaScript has issues with very large numbers so web3.js uses a BigNumber library and they recommend keeping things in Wei in your code until users see it (docs).

Account Balances. Web3.js provides a lot more convenience methods here, and another one used in the test below is web3.eth.getBalance(some_address). Recall that funds sent to the contract are in the contract itself until suicide is called.

Inside the contract(Briefing, office(accounts) {…}; body stick this additional test. In the highlighted method below, the test has a second user (accounts[one]) buy a ticket for ticketPrice. Then information technology checks that the contract's balance has increased by the ticketPrice sent and that the second user has been added to the listing of registrants.

In this test buyTicket is a Transaction:

          it("Should permit you buy a ticket", function(done) {
var c = Conference.at(Briefing.deployed_address);
Conference.new({ from: accounts[0] }).then(
part(conference) {
var ticketPrice = web3.toWei(.05, 'ether');
var initialBalance = web3.eth.getBalance(briefing.address).toNumber();
briefing.buyTicket({ from: accounts[1], value: ticketPrice })
.then(
function() {
var newBalance = web3.eth.getBalance(briefing.address).toNumber();
var departure = newBalance - initialBalance;
assert.equal(difference, ticketPrice, "Difference should exist what was sent");
render conference.numRegistrants.call();
}).and so(
part(num) {
assert.equal(num, 1, "there should be 1 registrant");
return conference.registrantsPaid.call(accounts[1]);
}).so(function(amount) {
affirm.equal(corporeality.toNumber(), ticketPrice, "Sender'southward paid but is not listed");
done();
}).catch(done);
}).catch(washed);
});

Transactions are Signed. Dissimilar previous function calls this is a transaction sent funds, and then under the hood the second user (accounts[ane]) is signing the transaction call buyTicket() with their key. (In geth the user would have to enter a countersign to approve this transaction or unlock their account earlier sending funds.)

toNumber(). Sometimes results from Solidity returned take to be converted from hex. If it might be a actually big number go with web3.toBigNumber(numberOrHexString) because Javascript can mess up big numbers.

Writing a Exam for a Contract Sending a Transaction

Finally, for sanity, let's make sure the refundTicket method works and can only be activated by the organizer. Here's a examination for it:

          it("Should issue a refund by owner only", function(done) {
var c = Briefing.at(Briefing.deployed_address);
Conference.new({ from: accounts[0] }).then(
function(conference) {
var ticketPrice = web3.toWei(.05, 'ether');
var initialBalance = web3.eth.getBalance(briefing.accost).toNumber();
briefing.buyTicket({
from: accounts[1], value: ticketPrice }).so(
office() {
var newBalance = web3.eth.getBalance(briefing.accost).toNumber();
var difference = newBalance - initialBalance;
assert.equal(difference, ticketPrice, "Difference should be what was sent");
// At present endeavor to issue refund as second user - should neglect
render conference.refundTicket(accounts[one], ticketPrice, {from: accounts[1]});
}).then(function() {
var balance = web3.eth.getBalance(briefing.address).toNumber();
assert.equal(web3.toBigNumber(residual), ticketPrice, "Residue should exist unchanged");
// Now try to issue refund as organizer/owner - should piece of work
return conference.refundTicket(accounts[1], ticketPrice, {from: accounts[0]});
}).then( function() {
var postRefundBalance = web3.eth.getBalance(conference.accost).toNumber();
assert.equal(postRefundBalance, initialBalance, "Balance should be initial balance");
washed();
}).catch(done);
}).catch(washed);
});

The corresponding Solidity part for the test above is here:

          role            refundTicket(address recipient, uint amount) public returns (bool success) {
if (msg.sender != organizer) { return false; }
if (registrantsPaid[recipient] == amount) {
address myAddress = this;
if (myAddress.balance >= amount) {
recipient.send(corporeality);
Refund(recipient, corporeality);
registrantsPaid[recipient] = 0;
numRegistrants--;
return true;
}
}
return false;
}

Sending ether from a contract. The address myAddress = this; line shows how to get the conference instance's accost, so you lot tin cheque the balance in the subsequent line (or just apply this.balance). Also the recipient.ship(corporeality) method is where the contract sends funds back to recipient.

Transactions cannot return results to web3.js. Note this! The refundTicket function returns a bool simply this cannot exist checked in your test. This method is a transaction (i.e., something that modifies values or transport ether), and the result of a transaction to web3.js is a transaction hash (if you printed the outcome it'll be a long hex/weird-looking object). So why add a return value to the refundTicket call at all? The return value tin can be read in Solidity, such as past some other contract that calls refundTicket(). So Solidity contracts can read return values from a transaction, but web3.js transaction calls cannot. On the other mitt, other contracts can't use Events (discussed below) which is how you can monitor transactions in web3.js, or check whether a transaction has modified example variables in a subsequent test promise using call().

More than on sendTransaction(). When you call a transaction similar buyTicket() or refundTicket() using web3.js (which uses web3.eth.sendTransaction), the transaction does not execute correct abroad. Instead the transaction is submitted to the network of miners, and the code does not run until one of those miners scores a block and the transaction is mined into the blockchain. And so to verify a transaction y'all accept to wait for it to go far onto the blockchain and so back to your local node. With testrpc this may be seem instantaneous considering it's then fast but on a live network it will be slower.

Events. Instead of using return values y'all tin can listen for events in web3.js. The smart contract example has these events:

          upshot Deposit(address _from, uint _amount);
event Refund(address _to, uint _amount);

And they are triggered in buyTicket() and refundTicket(). You can see these logged in the output of testrpc when called. To listen for them, y'all can also add web3.js listeners. At time of writing I haven't been able to log events inside of truffle tests but take logged them in an app:

          Conference.new({ from: accounts[0] }).then(
office(conference) {
var effect = conference.allEvents().watch({}, '');
// or employ conference.Eolith() or .Refund()
event.watch(function (error, event) {
if (fault) {
console.log("Mistake: " + error);
} else {
console.log("Upshot: " + consequence.issue);
}
});

Filters. Instead of checking all events in a higher place which may pb to a lot of polling, filters could be used instead. They permit you to starting time and stop watching for them when your transactions are washed. More than on filters can be plant in the Solidity docs.

Overall, using events and filters are cheaper in terms of gas than checking variables and so might be useful if you need to verify transactions on the live network.

Gas. Upwards to this point we haven't needed to hash out gas at all, it commonly doesn't need to be explicitly set with testrpc. Equally you lot move to geth and and then the live network it volition. In your transaction calls you can send gas implicitly inside the {from: __, value: __, gas: __} objects. Web3.js has a call for checking the gas toll web3.eth.gasPrice (The result of this is not how much gas you should send with your transaction but the price of 1 unit of gas or stride. For how much gas y'all should transport for now its probably best to ship something close to the gasLimit and so its sure to run. Correct now the maximum gas allowed in a cake is 3141592. I just use 3000000). The Solidity compiler also has a flag you lot can call from the command line to get a summary of gas expenditures for your contract: solc — gas YourContract.sol. Here's the output for Conference.sol:

Creating a DApp UI for your contract

This next section assumes you might be new to some web development practices, just in example.

All the truffle tests written above are using JavaScript methods re-usable in a front-stop UI. Add together your UI to the truffle directory app/. On running truffle build it will be compiled along with contract configuration stuff to the build/ directory. When developing use truffle watch to constantly compile whatsoever changes in app/* to build/*. Then reload what's in the build/ directory in your browser. (truffle serve tin also run a webserver for you from build/.)

In the app/ directory there'll be some boilerplate started for you:

alphabetize.html already loads app.js:

So nosotros can just add some code to app.js.

app.js has a console.log with "Howdy from Truffle!" that volition show up in your browser'due south programmer console. Offset truffle sentinel in the project root directory and then open build/alphabetize.html in a browser window, and open the browser'south developer console (In a lot of browsers like Chrome, right-click » Audit Element and switch to the Console tab below.)

In app.js, add a window.onload function that'll be called when the page loads. This snippet below will confirm web3.js is loaded and show all the accounts bachelor. [Note: your testrpc node should still be running.]

          window.onload = role() {
var accounts = web3.eth.accounts;
console.log(accounts);
}

Come across if that prints an array of accounts to your browser console.

Now you can just copy some functions from tests/conference.js (remove the assertions since those are for testing), and output what's returned to the panel to confirm its working. Here'south an example:

          window.onload = function() {
var accounts = web3.eth.accounts;
var c = Conference.at(Conference.deployed_address);
Briefing.new({ from: accounts[0] }).then(
function(conference) {
var ticketPrice = web3.toWei(.05, 'ether');
var initialBalance = web3.eth.getBalance(conference.accost).toNumber();
panel.log("The briefing'southward initial balance is: " + initialBalance);
conference.buyTicket({ from: accounts[1], value: ticketPrice }).and so(
part() {
var newBalance = web3.eth.getBalance(conference.address).toNumber();
console.log("After someone bought a ticket it'south: " + newBalance);
return briefing.refundTicket(accounts[1], ticketPrice, {from: accounts[0]});}).then(
function() {
var balance = web3.eth.getBalance(conference.accost).toNumber();
console.log("Afterwards a refund it'southward: " + balance); }); }); };

The code above should output:

Now using whatever web tools you prefer, jQuery, ReactJS, Shooting star, Ember, AngularJS, etc., y'all can outset building a DApp UI in app/for interacting with an Ethereum smart contract! Below is a super simple jQuery-based UI equally an example.

Here'southward the index.html. And here's the app.js.

At present that I'm interacting with the smart contract in a UI I'chiliad realizing it'd exist skilful to add checks to make sure the aforementioned user can't register twice. Also since this is running on testrpc, which is really fast, it'd exist good to switch to geth and make sure the transactions are still responsive to the user. Otherwise the UI should have some loading messages and disabled buttons while the transactions are being candy if they're going to have a while.

Trying geth. If yous're using geth, this line was working for me (geth v1.2.3):

          geth --rpc --rpcaddr="0.0.0.0" --rpccorsdomain="*" --mine --unlock='0 1' --verbosity=five --maxpeers=0 --minerthreads='four' --networkid '12345' --genesis test-genesis.json        

This unlocks 2 accounts, 0 and 1. Note:
1. You may demand to enter the passwords to both accounts later on the geth console starts upwardly.
two. You volition also need a test-genesis.json file with both of your accounts well-funded under 'alloc' in the test-genesis.json.)
3. Finally, for geth y'all may need to add gas when calling the constructor:

          Conference.new({from: accounts[0], gas: 3141592})        

Then re-practice the whole truffle deploy, truffle build affair.

Code for this tutorial. Again, all the code presented in this tutorial is in this repo.

Auto-generating UIs from contracts. SilentCicero has also built a tool called DApp Builder to auto-generate from a Solidity contract HTML, jQuery and web3.js calls you can modify. This is as well starting to be a common theme of some other smart contract dev tools coming out.

Ok tutorial over! This last part was a walkthrough of just one set of tools, mainly Truffle and testrpc. Even within ConsenSys, dissimilar developers use different tools and frameworks. You might find tools out there that are a amend fit for you, and some things may change in a few months (Souptacular keeps an updated gitbook of resources and notes). Just this workflow has helped me get started learning to build DApps.

(⊙ω⊙) wonk wonk

Thanks to Joseph Grub for a lot of proofreading and suggestions, as well as Christian Lundkvist, Daniel Novy, Jim Berry, Peter Borah and Tim Coulter for corrections and debugging help, and Tim Coulter, Nchinda Nchinda and Mike Goldin for helping with the DApp Front-end Steps diagram.

by Eva Shon
UX Designer
ConsenSys

More than technical tutorials

  • A Guide to Events and Logs in Ethereum Smart Contracts
  • Introduction to zk-SNARKs
  • How to Send Money Using Python
  • How to Fetch and Update Information From Ethereum with React and SWR

Subscribe to our Ethereum developer newsletter

Get the latest tutorials, tools, and pro tips straight to your inbox.

Where To Put Code For Smart Contracts?,

Source: https://medium.com/@ConsenSys/a-101-noob-intro-to-programming-smart-contracts-on-ethereum-695d15c1dab4

Posted by: jacobspactink.blogspot.com

0 Response to "Where To Put Code For Smart Contracts?"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel