New

Creating and Deploying Ethereum Smart Contract

In this section, we would implement and deploy the smart contract for

our use case.

The crowdsourcing contract is in ethereum/contract folder. Open the CrowdSourceContract.sol file. We will go

over the important code snippets of our contract. Our contract is written in

Solidity programming language. There are three main components to look at:

CrowdFunding - This is the

contract class.

FundingProject – A custom type

that hold project details as part of the contract.

Funder – A custom type

that holds funder details as part of the contract.

Let’s walkthrough the code:

We first specify the Solidity version required to compile our

contract.

pragma solidity ^0.4.11;

We then create the CrowdFunding

contract using the contract keyword

contract CrowdFunding {

The CrowdFunding contract contains the FundingProject and Funder custom types with required attributes. We then create instances of the custom types.

//Funding project details
    struct FundingProject {
        
        string name;
        string email;
        string website;
        uint minimumfunds;
        uint amountraised;
        address owner;
        string status;
      
    }
    
    //Funder who funds project.
    struct Funder {
        string name;
        address fundedby;
        uint amount;
    }

//Multiple funders can fund project
    Funder[] public funders;
    
    //Instance
    FundingProject public fundingproject

Next, we define methods/operations that would be exposed by our

contract.

The CrowdFunding() method shown below is the constructor of our contract which would initialize the project details. It expects parameters that are used to initialize the FundingProject type. We will show you how to pass these parameters once we instantiate the contract through our wallet interface in the next section.

function CrowdFunding (        
        string _name,
        string _email,
        string _website,
        uint _minimumfunds,
        address _owner        
        )
    {
       	
 //convert to ether
uint minimumfunds = _minimumfunds * 1 ether;
uint amountraised = 0;
fundingproject = 
FundingProject(_name,_email,_website,
minimumfunds,amountraised,_owner,
"Funding Started");
       
    }

Next, we initialize the Funder

type and assign it to the funders

array as part of the fundProject()

method. The attribute amountraised of

the FundingProject type will be

updated to reflect the funder’s amount. It means the funder has provided

funding of that amount value. If the attribute amountraised is greater than minimumfunds

i.e. if the project meets the funding target then the amount is sent to the

beneficiary account named ProjectAI.

This is done using the send() method

of the FundingProject.owner

attribute. Following shows the code snippet 

fundingproject.owner.send(fundingproject.amountraised)

The important thing to note is that the amount reaches the ProjectAI

account only when minimum funding amount is raised. Until that duration, the

amount transferred from Funder’s account is put on hold by the contract.

The below fundProject() method uses the payable modifier to receive ethers from the application (i.e., from Funders account who is funding the project)

function fundProject( string name) public payable {

if (stringsEqual(fundingproject.status ,"Funding Completed")) revert();
	funders.push(Funder({
				name: name,
				fundedby: msg.sender,
				amount: msg.value
			   }) 
			);
	 fundingproject.amountraised =	    
                fundingproject.amountraised + msg.value ;

if (fundingproject.amountraised >= 
               fundingproject.minimumfunds) {
				                 
              if(!fundingproject.owner.send(fundingproject.amountraised )) revert();				 
               fundingproject.status = "Funding Completed";
	} 
	else {		   			
                         fundingproject.status = "In Progress";
	}
}

Next, we define thestopFundRaising() method. The said method returns all the money to the

respective Funders (if the funding target is not met) by iterating through the

funders array and calling the send()

method of Funder.fundedBy attribute for

each funder object in the array. Following shows the code snippet  -

funders[p].fundedby.send(funders[p].amount)

The stopFundRaising() method

uses the payable modifier to send

ethers from the contract to respective funders account.

function  stopFundRaising() public payable {
    	 if (stringsEqual(fundingproject.status ,"Funding Completed")) revert();
    	 fundingproject.status = "Funding Stopped";
    	 //return money to all funders
    	 for (uint p = 0; p < funders.length; p++) {
    	 	if(!funders[p].fundedby.send(funders[p].amount)) throw;
    	 }
    	 fundingproject.amountraised = 0;
    }

Next, we define the getProjectStatus() constant method, that displays the status of the project at any interval.

function getProjectStatus() public constant	returns(string) {
    		return (fundingproject.status);
}

We now have our CrowdFunding

contract ready, the next step will be to deploy the same. You can copy the

content of the CrowdSourceContract.sol file and navigate back to Ethereum

Wallet application.  Click on Contracts from the top menu.  On contracts window, navigate to Deploy New Contract. Select Main Account as the From option.

Paste the copied content inside the Solidity Contract Source code window. The resulting contract will

be converted to bytecode once it is successfully compiled. If there were an

error in the contract, you would see a message “could not compile source code.”

Once the contract is compiled successfully, select the contract Crowd Funding from Select Contract to Deploy dropbox as shown in the figure below and

enter the following details:

  • Enter name as ProjectAI
  • Enter any email address and website
  • For minimum funds, enter 1000. This is the minimum amount to be raised for this crowdfunding project.
  • Enter the address of account ProjectAI (if you recall, we had copied and saved this earlier)
  • Click Deploy

On the Create contract

window, you would see the transaction fee and gas price for deploying the

contract as shown in the figure below. Enter the password of the Main Account and click Send Transaction.

If you go to Wallets tab and scroll down to the Latest Transactions section, you would see “Crowdsourcing Contract” being committed. Once all the confirmations are done, click on the transaction entry. You would see the transaction details and public address of the contract in the To column as shown in the figure below.

Click on the Crowd Funding public address link, and you would see the contract details. You can verify the contract details entered earlier. You will also see the status of the project as Funding Started as shown in the figure below.

Now, in the Select function

drop down, select Fund Project method

and enter name as “Fund from Funder 1”. In the Execute from option select Funder 1 and specify 700 as ether amount

as shown in the figure below.

Click Execute. On the Execute Contract window, specify the password

for Funder1 and click Send Transaction. You should see the

amount raised as 700000000000000000000 and status of the project changed as “In

progress.” The 700000000000000000000 value is in wei units (1 Ether =

1000000000000000000 wei), the Wallet displays currency in wei units. You can

verify the transaction details in the *Latest

Transaction* view, and you should also see 700 ethers and transaction fee

deducted from the Funder1 balance.

Next, go back to the contract (either by clicking on contract link

from the transaction view or by selecting Contracts

from the top menu and clicking on the specific contract address from the custom

contract list).

Now, select Fund Project method from Select function dropdown and this time, select Funder2 and transfer 350 ethers as shown below.

Click Execute and send the transaction.  Once the transaction is committed, you will see the status of the project changed to Funding Completed. You should also see 350 ethers and transaction fee deducted from the Funder2 balance. The ProjectAI account would be credited with 1050 ether amount.

Next, we would execute the Stop Funding use case, where the amount funded by Funders would be transferred back to the Funders wallet if the funding target is not met.

For this use case, we would follow similar steps as described earlier

with the addition of executing the Stop Funding function. Let’s call this as

Use Case 2 (we would reference this later). To implement ‘Stop Funding’ use

case, carry out the following steps :

  1. Create a new contract as per earlier guidelines and copy the content of CrowdFunding.sol in the new contract
  2. Select Crowd Funding contract and provide the necessary details. Provide minimum funds as 500 and execute the contract.
  3. Verify the project status as ‘Funding Started’.
  4. Select the Fund Project method and transfer 200 ethers from Funder1 account. Execute the transaction.
  5. Verify the minimum funding amount value is 200 for this project after the transaction is executed.
  6. Now, execute the Stop Fund Raising method, select the execute from as Main Account (or Funder1 Account). Click Execute.
  7. The status of the project would be Funding Stopped, and you will see the 200 Ether transferred back to Funder1 Account. You can verify the balance of the Funder1 Account.

In the next article, we will look at how to invoke the smart contract from a web application