Introduction to Ethereum - Part 4


Bhaskar S 01/05/2018


Overview

In this article, we finally put together a decent Smart Contract to demonstrate the simple vehicle buying use-case (involving the buyer, the dealer, and the dmv) that we laid out in our first introductory article Introduction to Blockchain.

The following are the aspects involved in demonstrating our use-case:

Hands-on with Smart Contracts using Solidity

In the previous article Part 3 of this series, we introduced the concept of defining multiple contract(s) in a single .sol file, as well as the use of a modifier contract to enforce constraint check(s) prior to executing a function.

Since we need to ensure the buyer has included enough ethers to cover for the cost of the vehicle as well as the processing fees, we will extract the modifier contract into a separate .sol file, so that it can be commonly applied to any Smart Contract (either from the dmv or the dealer).

The following is the extracted and enhanced Solidity contract code called AmountOwed2.sol located in the directory /home/polarsparc/Ethereum/src:

AmountOwed2.sol
pragma solidity ^0.4.15;

/*
 * This AmountOwed contract implements a common function modifier to check the value of tranfer
 * satisfies the amount owed to the service provider (dealer or dmv)
 */

contract AmountOwed2 {
    event AmountEvt(uint flag, uint value, uint amount, address context);

    // Modifiers can be used to change the behaviour of any function in a contract, such as checking
    // a condition prior to executing the function. Modifiers are inheritable properties of contracts
    // and may be overridden by derived contracts
    modifier validateAmount(uint amt, address context) {
        AmountEvt(1, msg.value, amt, context);
        require(msg.value >= amt);
        AmountEvt(2, msg.value, amt, context);
        _; // Function body
        AmountEvt(3, msg.value, amt, context);
    }
}

Since the Smart Contract deployed by the dealer (vehicle purchase) needs to interact with the Smart Contract deployed by the dmv (for vehicle registration), we will create an abstract contract defining the interface of the dmv contract. An abstract contract is a Solidty contract that defines the functions without any implementation details. This is similar to interfaces in commonly used object-oriented programming languages like Java, C++, etc.

The following is the abstract Solidity contract code for the dmv called IDmvRegister.sol located in the directory /home/polarsparc/Ethereum/src:

IDmvRegister.sol
pragma solidity ^0.4.15;

/*
 * DmvRegister contract interface
 */

contract IDmvRegister {
    function getFees() public view returns (uint);
    function getLicense(uint vin) public view returns (uint);
    function registerVehicle(uint vin, address buyer) public payable;
}

The following is the concrete Solidity contract code for the dmv called DmvRegister.sol located in the directory /home/polarsparc/Ethereum/src:

DmvRegister.sol
pragma solidity ^0.4.15;

import "./IDmvRegister.sol";
import "./AmountOwed2.sol";

/*
 * A DmvRegister contract is first created in the Ethereum  blockchain by the dmv. Once deployed
 * the contract address is used by the dealer in the creation of the Vehicle3 contract. When the
 * dealer receives  the  payment for the  vehicle from  the  buyer, the  vehicle registration is
 * triggered from the buyVehicle function in the Vehicle3 contract.
 */

contract DmvRegister is IDmvRegister, AmountOwed2 {
    struct OwnerLicense {
        bool registered;
        uint license;
        address owner;
    }

    uint _counter;
    uint _fees;
    address _dmv;
    mapping (uint => OwnerLicense) _licenseTbl;

    event RegisteredEvt(uint flag, uint vin, uint license, uint fees, address buyer);
    
    function getFees() public view returns (uint) {
        return _fees;
    }
    
    function getLicense(uint vin) public view returns (uint) {
        return _licenseTbl[vin].license;
    }
    
    // The keyword 'payable' is important for accepting ethers from the sender
    function registerVehicle(uint vin, address buyer) public payable validateAmount(_fees, _dmv) {
        var lic = _licenseTbl[vin];
        if (!lic.registered) {
            RegisteredEvt(1, vin, lic.license, msg.value, buyer);
            lic.owner = buyer;
            lic.license = _counter;
            lic.registered = true;
            _counter++;
            _dmv.transfer(_fees);
            RegisteredEvt(2, vin, lic.license, msg.value-_fees, buyer);
        } else {
            RegisteredEvt(3, vin, lic.license, msg.value, buyer);
        }
    }
    
    function DmvRegister(uint fees) public {
        _counter = 101;
        _fees = fees;
        _dmv = msg.sender;
        RegisteredEvt(0, 0, 0, fees, address(0));
    }
}

Let us explain some of the important keywords used in the DmvRegister.sol file shown above.

The keyword import followed by a path to a .sol file includes the contents of the specified file into the current scope. This is similar to the import statement in Javascript.

The keyword struct is used to define a complex data type, similar to the one from the C programming language. In our use-case, we define a custom data type called OwnerLicense to encapsulate a boolean flag indicating if the vehicle is registered, the license number and the owner of the vehicle.

The contract DmvRegister supports multiple inheritence by implementing one interface IDmvRegister and extending a contract AmountOwed2.

The keyword mapping is used to define a data structure that is similar to a hash-table from the Java programming language. The left-hand side of symbol => defines the type of the key, while the right-hand side defines the type of the value. In our use-case, the key is of type uint representing the vin number and the value is of type OwnerLicense. One important difference compared to a hash-table in Java is that every key value exists and is initialized to the default value of the value type. For example, for a new key with value 1111, the corresponding mapped value would be a default value of OwnerLicense with a false for registered, zero for license, and 0x0 for owner. In other words, the mapped value will never be null like in Java.

The method transfer on an address transfers the specified value to the balance on the invoked address. In our use-case, we are transferring the processing fees to the dmv.

An instance of the contract DmvRegister will be deployed by the dmv, such that the dealer contract can transfer ethers on behalf of the buyer to fulfill the processing fees of registering the vehicle by invoking the method registerVehicle().

The following is the concrete Solidity contract code for the dealer called Vehicle3.sol located in the directory /home/polarsparc/Ethereum/src:

Vehicle3.sol
pragma solidity ^0.4.15;

import "./IDmvRegister.sol";
import "./AmountOwed2.sol";

/*
 * A Vehicle instance is first created in the Ethereum blockchain by the dealer.
 * Once the payment is received, the dealer transfers ownership to the buyer.
 */

contract Vehicle3 is AmountOwed2 {
    enum DealStatus { Open, Closed }
    
    uint _vin;
    uint _cost;
    uint _fees;
    address _buyer;
    address _dealer;
    DealStatus _status;
    IDmvRegister _dmvif;
    
    event BoughtEvt(uint flag, uint vin, uint value, address buyer);
    
    function getVin() public view returns (uint) {
        return _vin;
    }
    
    function getCost() public view returns (uint) {
        return _cost;
    }
    
    function getOwner() public view returns (address) {
        return _buyer;
    }
    
    function getDealer() public view returns (address) {
        return _dealer;
    }
    
    function getStatus() public view returns (DealStatus) {
        return _status;
    }
    
    // The keyword 'payable' is important for accepting ethers from the buyer
    function buyVehicle() public payable validateAmount(_cost+_fees, _dealer) {
        uint _gas = 1000000;
        uint _amt = msg.value;
        // Only the assigned owner can close the deal
        if (msg.sender == _buyer) {
            BoughtEvt(1, _vin, _amt, _buyer);
            _status = DealStatus.Closed;
            _dealer.transfer(_cost);
            _amt = _amt - _cost;
            BoughtEvt(2, _vin, _amt, _buyer);
            _dmvif.registerVehicle.value(_amt).gas(_gas)(_vin, _buyer);
            _amt = _amt - _fees;
            BoughtEvt(3, _vin, _amt, _buyer);
        } else {
            BoughtEvt(4, _vin, msg.value, _buyer);
        }
    }
    
    // fees will include the gas price
    function Vehicle3(uint vin, uint cost, uint fees, address buyer, address dmvcon) public {
        _vin = vin;
        _cost = cost;
        _fees = fees;
        _buyer = buyer;
        _dealer = msg.sender;
        _status = DealStatus.Open;
        _dmvif = IDmvRegister(dmvcon);
        BoughtEvt(0, _vin, 0, _buyer);
    }
}

The method value on a payable function of a contract allows one to transfer some ethers to the balance of the contract address.

Similarly, the method gas on a payable function of a contract allows one to pay for the gas used in processing of that function.

As is evident from the contract code above, one can chain the methods value and gas when invoking the payable function registerVehicle on the dmv contract. Also, notice the arguments for the invoked function come at the last in the chain.

In the constructor of the dealer contract Vehicle3, an instance of the dmv contract object is created by passing the contract address of the dmv contract to the abstract contract interface IDmvRegister.

An instance of the contract Vehicle3 will be deployed by the dealer when the buyer intends to buy a vehicle at a certain price (includes the cost of the vehicle plus the cost of processing the registration of the vehicle with the dmv). When the buyer sends a transaction message (with the payment in ethers) to the payable method buyVehicle(), the contract is executed and the deal is closed. This encompasses registering the vehicle with the dmv.

For convenience, we have enhanced the custom Javascript utility script with some helper variable(s) and a function to extract and display information on account balances. The following is the custom Javascript script called UtilScripts.js located in the directory /home/polarsparc/Ethereum/bin:

UtilScripts.js
var bank = "0xef17ec5df3116dea3b7abaf1ff3045639453cc76";
var buyer = "0x35ddac855e0029676f489dafca9ab405a348317c";
var dealer = "0x46bf8994c8702919434271d89bcad8abec915612";
var dmv = "0x518a6377a3863201aef3310da41f3448d959a310";

var vin = 1234567890
var cost = 4000000000000000000
var fees = 1000000000000000000
var gas = 1000000;
var total = 5000000000000000000

function showBalances() {
  var i = 0;
  eth.accounts.forEach(function(e) {
     console.log("---> eth.accounts["+i+"]: " + e + " \tbalance: " + web3.fromWei(eth.getBalance(e), "ether") + " ether");
     i++;
  })
};

The following are the steps to demonstrate the simple vehicle buying use-case (involving a buyer, a dealer, and the dmv):

Step - 01

Compile DmvRegister.sol using the Solidity compiler to generate a Javascript file (with .js file extension) with both the abi as well as the bytecode by executing the following command:

$ echo "var dmvregister=`solc --optimize --combined-json abi,bin,interface src/DmvRegister.sol`" > bin/DmvRegister.js

The above command will generate the desired Javascript file called DmvRegister.js located in directory /home/polarsparc/Ethereum/bin encoded as JSON.

Step - 02

Compile Vehicle3.sol using the Solidity compiler to generate a Javascript file (with .js file extension) with both the abi as well as the bytecode by executing the following command:

$ echo "var vehicle3=`solc --optimize --combined-json abi,bin,interface src/Vehicle3.sol`" > bin/Vehicle3.js

The above command will generate the desired Javascript file called Vehicle3.js located in directory /home/polarsparc/Ethereum/bin encoded as JSON.

Step - 03

Load the three Javascript files UtilScripts.js, DmvRegister.js and Vehicle3.js by executing the following commands one at a time in the Javascript shell prompt:

> loadScript("./bin/UtilScripts.js")

> loadScript("./bin/DmvRegister.js")

> loadScript("./bin/Vehicle3.js")

Step - 04

Check to ensure the variable dmvregister is initialized by executing the following command in the Javascript shell prompt:

> dmvregister

The following would be the typical output:

Output.1

{
  contracts: {
    src/AmountOwed2.sol:AmountOwed2: {
      abi: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"flag\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"context\",\"type\":\"address\"}],\"name\":\"AmountEvt\",\"type\":\"event\"}]",
      bin: "60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00a165627a7a723058201ad282abd92f245df43f5c30716a945b232176ef484eb7ae18c8a01395dd33160029"
    },
    src/DmvRegister.sol:DmvRegister: {
      abi: "[{\"constant\":true,\"inputs\":[{\"name\":\"vin\",\"type\":\"uint256\"}],\"name\":\"getLicense\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"vin\",\"type\":\"uint256\"},{\"name\":\"buyer\",\"type\":\"address\"}],\"name\":\"registerVehicle\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getFees\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"fees\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"flag\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"vin\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"license\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"buyer\",\"type\":\"address\"}],\"name\":\"RegisteredEvt\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"flag\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"context\",\"type\":\"address\"}],\"name\":\"AmountEvt\",\"type\":\"event\"}]",
      bin: "6060604052341561000f57600080fd5b6040516020806104b18339810160405280805160656000908155600182905560028054600160a060020a03191633600160a060020a03161790559092507fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e691508080848160405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a1506103f6806100bb6000396000f3006060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663b2dd1212811461005b578063cca10a2114610083578063db8d55f11461009c575b600080fd5b341561006657600080fd5b6100716004356100af565b60405190815260200160405180910390f35b61009a600435600160a060020a03602435166100c4565b005b34156100a757600080fd5b6100716103c4565b60009081526003602052604090206001015490565b60018054600254600092600160a060020a03909116907fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c903484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1348290101561014057600080fd5b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60023484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16000858152600360205260409020805490935060ff161515610300577fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e66001868560010154348860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a16002838101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038781169190911790915560008054600180880191909155865460ff19168117875581548101909155915491549116906108fc81150290604051600060405180830381858888f19350505050151561029457600080fd5b7fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e6600286856001015460015434038860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a1610364565b7fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e66003868560010154348860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a15b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60033484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a15050505050565b600154905600a165627a7a72305820fbca4691cd855134e337de1865b5bb119ca255ace4c88782cc2c65f85552c9820029"
    },
    src/IDmvRegister.sol:IDmvRegister: {
      abi: "[{\"constant\":true,\"inputs\":[{\"name\":\"vin\",\"type\":\"uint256\"}],\"name\":\"getLicense\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"vin\",\"type\":\"uint256\"},{\"name\":\"buyer\",\"type\":\"address\"}],\"name\":\"registerVehicle\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getFees\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]",
      bin: ""
    }
  },
  version: "0.4.19+commit.c4cbbb05.Linux.g++"
}
Step - 05

Create a contract object called dmvregister_contract by executing the following command in the Javascript shell prompt:

> var dmvregister_contract = eth.contract(JSON.parse(dmvregister.contracts['src/DmvRegister.sol:DmvRegister'].abi))

Check to ensure the variable dmvregister_contract is initialized by executing the following command in the Javascript shell prompt:

> dmvregister_contract

The following would be the typical output:

Output.2

{
  abi: [{
      constant: true,
      inputs: [{...}],
      name: "getLicense",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: false,
      inputs: [{...}, {...}],
      name: "registerVehicle",
      outputs: [],
      payable: true,
      stateMutability: "payable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getFees",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      inputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "constructor"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}, {...}],
      name: "RegisteredEvt",
      type: "event"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "AmountEvt",
      type: "event"
  }],
  eth: {
    accounts: ["0xef17ec5df3116dea3b7abaf1ff3045639453cc76", "0x35ddac855e0029676f489dafca9ab405a348317c", "0x46bf8994c8702919434271d89bcad8abec915612", "0x518a6377a3863201aef3310da41f3448d959a310"],
    blockNumber: 0,
    coinbase: "0xef17ec5df3116dea3b7abaf1ff3045639453cc76",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 18000000000,
    hashrate: 0,
    mining: false,
    pendingTransactions: [],
    protocolVersion: "0x3f",
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(options, callback, filterCreationErrorCallback),
    getAccounts: function(callback),
    getBalance: function(),
    getBlock: function(),
    getBlockNumber: function(callback),
    getBlockTransactionCount: function(),
    getBlockUncleCount: function(),
    getCode: function(),
    getCoinbase: function(callback),
    getCompilers: function(),
    getGasPrice: function(callback),
    getHashrate: function(callback),
    getMining: function(callback),
    getPendingTransactions: function(callback),
    getProtocolVersion: function(callback),
    getRawTransaction: function(),
    getRawTransactionFromBlock: function(),
    getStorageAt: function(),
    getSyncing: function(callback),
    getTransaction: function(),
    getTransactionCount: function(),
    getTransactionFromBlock: function(),
    getTransactionReceipt: function(),
    getUncle: function(),
    getWork: function(),
    iban: function(iban),
    icapNamereg: function(),
    isSyncing: function(callback),
    namereg: function(),
    resend: function(),
    sendIBANTransaction: function(),
    sendRawTransaction: function(),
    sendTransaction: function(),
    sign: function(),
    signTransaction: function(),
    submitTransaction: function(),
    submitWork: function()
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}
Step - 06

Create a variable called dmvregister_contract_txn to represent the contract transaction object, encapsulating the address of the dmv, the bytecode of the dmv contract, and a gas price. Execute the following expression in the Javascript shell as shown below:

> var dmvregister_contract_txn = { from: dmv, data: '0x'+dmvregister.contracts['src/DmvRegister.sol:DmvRegister'].bin, gas: gas }

Check to ensure the variable dmvregister_contract_txn is initialized by executing the following command in the Javascript shell prompt:

> dmvregister_contract_txn

The following would be the typical output:

Output.3

{
  data: "0x6060604052341561000f57600080fd5b6040516020806104b18339810160405280805160656000908155600182905560028054600160a060020a03191633600160a060020a03161790559092507fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e691508080848160405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a1506103f6806100bb6000396000f3006060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663b2dd1212811461005b578063cca10a2114610083578063db8d55f11461009c575b600080fd5b341561006657600080fd5b6100716004356100af565b60405190815260200160405180910390f35b61009a600435600160a060020a03602435166100c4565b005b34156100a757600080fd5b6100716103c4565b60009081526003602052604090206001015490565b60018054600254600092600160a060020a03909116907fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c903484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1348290101561014057600080fd5b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60023484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16000858152600360205260409020805490935060ff161515610300577fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e66001868560010154348860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a16002838101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038781169190911790915560008054600180880191909155865460ff19168117875581548101909155915491549116906108fc81150290604051600060405180830381858888f19350505050151561029457600080fd5b7fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e6600286856001015460015434038860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a1610364565b7fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e66003868560010154348860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a15b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60033484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a15050505050565b600154905600a165627a7a72305820fbca4691cd855134e337de1865b5bb119ca255ace4c88782cc2c65f85552c9820029",
  from: "0x518a6377a3863201aef3310da41f3448d959a310",
  gas: 1000000
}
Step - 07

Now we are ready to deploy our Smart Contract for the dmv called DmvRegister into our private Ethereum network.

Since the contract will be deployed by the dmv account, we need to unlock the dmv account before proceeding further.

To unlock the dmv account, execute the following command in the Javascript shell prompt:

> personal.unlockAccount(dmv)

This will prompt us for the password for the dmv account. The following would be the typical output:

Output.4

Unlock account 0x518a6377a3863201aef3310da41f3448d959a310
Passphrase: dmv
true

Create a contract instance object called dmvregister_contract_inst, by calling the new method on the contract object dmvregister_contract, passing a constructor argument for the processing fees (fees) and the contract transaction object dmvregister_contract_txn. Execute the following command in the Javascript shell prompt:

> var dmvregister_contract_inst = dmvregister_contract.new(fees, dmvregister_contract_txn)

Check to ensure the variable dmvregister_contract_inst is initialized by executing the following command in the Javascript shell prompt:

> dmvregister_contract_inst

The following would be the typical output:

Output.5

{
  abi: [{
      constant: true,
      inputs: [{...}],
      name: "getLicense",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: false,
      inputs: [{...}, {...}],
      name: "registerVehicle",
      outputs: [],
      payable: true,
      stateMutability: "payable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getFees",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      inputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "constructor"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}, {...}],
      name: "RegisteredEvt",
      type: "event"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "AmountEvt",
      type: "event"
  }],
  address: undefined,
  transactionHash: "0x67bb538323962381c32195c94d67f3d8a6c39caa074d12319e5dfb6ba4b79d42"
}
Step - 08

The above contract instance creation command will generate an Ethereum transaction that needs to be mined for the contract to be deployed into the private Blockchain network.

To check all the pending transactions, execute the following command in the Javascript shell prompt:

> eth.pendingTransactions

The following would be the typical output:

Output.6

[{
    blockHash: null,
    blockNumber: null,
    from: "0x518a6377a3863201aef3310da41f3448d959a310",
    gas: 1000000,
    gasPrice: 18000000000,
    hash: "0x67bb538323962381c32195c94d67f3d8a6c39caa074d12319e5dfb6ba4b79d42",
    input: "0x6060604052341561000f57600080fd5b6040516020806104b18339810160405280805160656000908155600182905560028054600160a060020a03191633600160a060020a03161790559092507fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e691508080848160405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a1506103f6806100bb6000396000f3006060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663b2dd1212811461005b578063cca10a2114610083578063db8d55f11461009c575b600080fd5b341561006657600080fd5b6100716004356100af565b60405190815260200160405180910390f35b61009a600435600160a060020a03602435166100c4565b005b34156100a757600080fd5b6100716103c4565b60009081526003602052604090206001015490565b60018054600254600092600160a060020a03909116907fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c903484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1348290101561014057600080fd5b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60023484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16000858152600360205260409020805490935060ff161515610300577fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e66001868560010154348860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a16002838101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038781169190911790915560008054600180880191909155865460ff19168117875581548101909155915491549116906108fc81150290604051600060405180830381858888f19350505050151561029457600080fd5b7fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e6600286856001015460015434038860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a1610364565b7fd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e66003868560010154348860405194855260208501939093526040808501929092526060840152600160a060020a03909116608083015260a0909101905180910390a15b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60033484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a15050505050565b600154905600a165627a7a72305820fbca4691cd855134e337de1865b5bb119ca255ace4c88782cc2c65f85552c98200290000000000000000000000000000000000000000000000000de0b6b3a7640000",
    nonce: 0,
    r: "0xbe24f8bd858f488a010aec0ca8e2790fa6baa7e9bd62fa8387f5a4e3827c23d3",
    s: "0x72038ff9a3ab3608f897d3c5e6fbd0603fb8205cee3962dc10eebda862712d05",
    to: null,
    transactionIndex: 0,
    v: "0x4d",
    value: 0
}]

Before we start the miner, we will display the account balances. To display account balances using the Javascript utility function showBalances, execute the following command in the Javascript shell prompt:

> showBalances()

The following would be the typical output:

Output.7

---> eth.accounts[0]: 0xef17ec5df3116dea3b7abaf1ff3045639453cc76  balance: 20 ether
---> eth.accounts[1]: 0x35ddac855e0029676f489dafca9ab405a348317c  balance: 10 ether
---> eth.accounts[2]: 0x46bf8994c8702919434271d89bcad8abec915612  balance: 5 ether
---> eth.accounts[3]: 0x518a6377a3863201aef3310da41f3448d959a310  balance: 3 ether
undefined

To start the miner with one thread, execute the following command in the Javascript shell prompt:

> miner.start(1)

Wait a few seconds (about 10 to 15 seconds) for the contract deployment transaction to be mined. The end result is that the contract will be deployed into our private Blockchain network.

Once the transaction is mined, we can stop the miner. Execute the following command in the Javascript shell prompt:

> miner.stop()

To retrieve the transaction details for the dmv contract deployment, execute the following command in the Javascript shell prompt:

> eth.getTransactionReceipt(dmvregister_contract_inst.transactionHash)

The following would be the typical output:

Output.8

{
  blockHash: "0xe3cd14751c51ef81cc3ae18d8ef8d4c0e00f892aef6d59c5f97640f85dc99e9d",
  blockNumber: 1,
  contractAddress: "0x1727b37a8a3334d62b5f669423a74517d18b9aeb",
  cumulativeGasUsed: 397004,
  from: "0x518a6377a3863201aef3310da41f3448d959a310",
  gasUsed: 397004,
  logs: [{
      address: "0x1727b37a8a3334d62b5f669423a74517d18b9aeb",
      blockHash: "0xe3cd14751c51ef81cc3ae18d8ef8d4c0e00f892aef6d59c5f97640f85dc99e9d",
      blockNumber: 1,
      data: "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000",
      logIndex: 0,
      removed: false,
      topics: ["0xd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e6"],
      transactionHash: "0x67bb538323962381c32195c94d67f3d8a6c39caa074d12319e5dfb6ba4b79d42",
      transactionIndex: 0
  }],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000002000010000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x2dc7ff0518bed8b62f821263e35e7b79ce21458c4ea3710108a95021d21f50d0",
  to: null,
  transactionHash: "0x67bb538323962381c32195c94d67f3d8a6c39caa074d12319e5dfb6ba4b79d42",
  transactionIndex: 0
}

The presence of a value for the contractAddress (0x1727b37a8a3334d62b5f669423a74517d18b9aeb) from the Output.8 indicates that the contract has been successfully deployed to our private Blockchain network.

Once again, let us display account balances using the Javascript utility function showBalances. Execute the following command in the Javascript shell prompt:

Before proceeding further, we will once again display the account balances. To display account balances using the Javascript utility function showBalances, execute the following command in the Javascript shell prompt:

> showBalances()

The following would be the typical output:

Output.9

---> eth.accounts[0]: 0xef17ec5df3116dea3b7abaf1ff3045639453cc76   balance: 45.007146072 ether
---> eth.accounts[1]: 0x35ddac855e0029676f489dafca9ab405a348317c  balance: 10 ether
---> eth.accounts[2]: 0x46bf8994c8702919434271d89bcad8abec915612  balance: 5 ether
---> eth.accounts[3]: 0x518a6377a3863201aef3310da41f3448d959a310  balance: 2.992853928 ether
undefined

Since the dmv deployed the contract DmvRegister into our private Blockchain, as expected, the dmv account incurred a small processing fees in the form of gas.

Step - 09

Define a variable called dmvregister_contract_addr that is initialized with the value of the deployed dmv contract address. Execute the following statement in the Javascript shell as shown below:

> var dmvregister_contract_addr = eth.getTransactionReceipt(dmvregister_contract_inst.transactionHash).contractAddress

To check the value of the contract transaction object variable dmvregister_contract_addr, execute the following command in the Javascript shell prompt:

Check to ensure the variable dmvregister_contract_addr is initialized by executing the following command in the Javascript shell prompt:

> dmvregister_contract_addr

The following would be the typical output:

Output.10

"0x1727b37a8a3334d62b5f669423a74517d18b9aeb"

To interact (invoke functions) with the deployed DmvRegister contract, we need an instance of the contract. To create an instance of the DmvRegister contract, invoke the at method on the contract object dmvregister_contract, passing in the value of the variable dmvregister_contract_addr as an argument. Execute the following command in the Javascript shell prompt:

> var dmvregister_obj = dmvregister_contract.at(dmvregister_contract_addr)

To check the value of the contract instance variable dmvregister_obj, execute the following command in the Javascript shell prompt:

> dmvregister_obj

The following would be the typical output:

Output.11

{
  abi: [{
      constant: true,
      inputs: [{...}],
      name: "getLicense",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: false,
      inputs: [{...}, {...}],
      name: "registerVehicle",
      outputs: [],
      payable: true,
      stateMutability: "payable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getFees",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      inputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "constructor"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}, {...}],
      name: "RegisteredEvt",
      type: "event"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "AmountEvt",
      type: "event"
  }],
  address: "0x1727b37a8a3334d62b5f669423a74517d18b9aeb",
  transactionHash: null,
  AmountEvt: function(),
  RegisteredEvt: function(),
  allEvents: function(),
  getFees: function(),
  getLicense: function(),
  registerVehicle: function()
}
Step - 10

The buyer walks into the auto dealership and expresses an intent to buy a vehicle. The dealer will create and deploy a Smart Contract representing the sale with the buyer for the desired vehicle (vin) at an agreed upon total cost (cost of the vehicle + the processing fees for vehicle registration at the dmv).

Check to ensure the variable vehicle3 is initialized by executing the following command in the Javascript shell prompt:

> vehicle3

The following would be the typical output:

Output.12

{
  contracts: {
    src/AmountOwed2.sol:AmountOwed2: {
      abi: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"flag\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"context\",\"type\":\"address\"}],\"name\":\"AmountEvt\",\"type\":\"event\"}]",
      bin: "60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00a165627a7a723058201ad282abd92f245df43f5c30716a945b232176ef484eb7ae18c8a01395dd33160029"
    },
    src/IDmvRegister.sol:IDmvRegister: {
      abi: "[{\"constant\":true,\"inputs\":[{\"name\":\"vin\",\"type\":\"uint256\"}],\"name\":\"getLicense\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"vin\",\"type\":\"uint256\"},{\"name\":\"buyer\",\"type\":\"address\"}],\"name\":\"registerVehicle\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getFees\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]",
      bin: ""
    },
    src/Vehicle3.sol:Vehicle3: {
      abi: "[{\"constant\":true,\"inputs\":[],\"name\":\"getStatus\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getDealer\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"buyVehicle\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getCost\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getVin\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"vin\",\"type\":\"uint256\"},{\"name\":\"cost\",\"type\":\"uint256\"},{\"name\":\"fees\",\"type\":\"uint256\"},{\"name\":\"buyer\",\"type\":\"address\"},{\"name\":\"dmvcon\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"flag\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"vin\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"buyer\",\"type\":\"address\"}],\"name\":\"BoughtEvt\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"flag\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"context\",\"type\":\"address\"}],\"name\":\"AmountEvt\",\"type\":\"event\"}]",
      bin: "6060604052341561000f57600080fd5b60405160a0806106a1833981016040528080519190602001805191906020018051919060200180519190602001805160008781556001879055600286905560038054600160a060020a03878116600160a060020a03199283161792839055600480543383169084161760a060020a60ff021916905560058054909216858216179091559294507f95220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bf9350909188918391166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1505050505061059b806101066000396000f3006060604052600436106100775763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634e69d560811461007c578063893d20e8146100b35780639cf6d1af146100e2578063a4e72902146100f5578063bd3e19d4146100ff578063bf20f94014610124575b600080fd5b341561008757600080fd5b61008f610137565b6040518082600181111561009f57fe5b60ff16815260200191505060405180910390f35b34156100be57600080fd5b6100c6610158565b604051600160a060020a03909116815260200160405180910390f35b34156100ed57600080fd5b6100c6610167565b6100fd610176565b005b341561010a57600080fd5b610112610543565b60405190815260200160405180910390f35b341561012f57600080fd5b610112610549565b60045474010000000000000000000000000000000000000000900460ff1690565b600354600160a060020a031690565b600454600160a060020a031690565b60008060025460015401600460009054906101000a9004600160a060020a03167fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60013484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a134829010156101fd57600080fd5b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60023484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1600354620f4240945034935033600160a060020a039081169116141561048c57600054600354600080516020610550833981519152916001918690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16004805474ff00000000000000000000000000000000000000001916740100000000000000000000000000000000000000001790819055600154600160a060020a039091169080156108fc0290604051600060405180830381858888f19350505050151561033a57600080fd5b600154600054600354919094039360008051602061055083398151915291600291908690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1600554600054600354600160a060020a039283169263cca10a219288928892166040517c010000000000000000000000000000000000000000000000000000000063ffffffff87160281526004810192909252600160a060020a031660248201526044016000604051808303818589803b151561041657600080fd5b88f1151561042357600080fd5b50506002546000546003805492909803976000805160206105508339815191529550935091508690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16104e4565b600054600354600080516020610550833981519152916004913490600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a15b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60033484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a150505050565b60015490565b60005490560095220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bfa165627a7a7230582031c62c3945703dc4333755b805a2120992c21af05e4cd84644a9e2b77c733b860029"
    }
  },
  version: "0.4.19+commit.c4cbbb05.Linux.g++"
}
Step - 11

Create a contract object called vehicle3_contract by executing the following command in the Javascript shell prompt:

> var vehicle3_contract = eth.contract(JSON.parse(vehicle3.contracts['src/Vehicle3.sol:Vehicle3'].abi))

Check to ensure the variable vehicle3_contract is initialized by executing the following command in the Javascript shell prompt:

> vehicle3_contract

The following would be the typical output:

Output.13

{
  abi: [{
      constant: true,
      inputs: [],
      name: "getStatus",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getOwner",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getDealer",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: false,
      inputs: [],
      name: "buyVehicle",
      outputs: [],
      payable: true,
      stateMutability: "payable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getCost",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getVin",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      inputs: [{...}, {...}, {...}, {...}, {...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "constructor"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "BoughtEvt",
      type: "event"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "AmountEvt",
      type: "event"
  }],
  eth: {
    accounts: ["0xef17ec5df3116dea3b7abaf1ff3045639453cc76", "0x35ddac855e0029676f489dafca9ab405a348317c", "0x46bf8994c8702919434271d89bcad8abec915612", "0x518a6377a3863201aef3310da41f3448d959a310"],
    blockNumber: 0,
    coinbase: "0xef17ec5df3116dea3b7abaf1ff3045639453cc76",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 18000000000,
    hashrate: 0,
    mining: false,
    pendingTransactions: [],
    protocolVersion: "0x3f",
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(options, callback, filterCreationErrorCallback),
    getAccounts: function(callback),
    getBalance: function(),
    getBlock: function(),
    getBlockNumber: function(callback),
    getBlockTransactionCount: function(),
    getBlockUncleCount: function(),
    getCode: function(),
    getCoinbase: function(callback),
    getCompilers: function(),
    getGasPrice: function(callback),
    getHashrate: function(callback),
    getMining: function(callback),
    getPendingTransactions: function(callback),
    getProtocolVersion: function(callback),
    getRawTransaction: function(),
    getRawTransactionFromBlock: function(),
    getStorageAt: function(),
    getSyncing: function(callback),
    getTransaction: function(),
    getTransactionCount: function(),
    getTransactionFromBlock: function(),
    getTransactionReceipt: function(),
    getUncle: function(),
    getWork: function(),
    iban: function(iban),
    icapNamereg: function(),
    isSyncing: function(callback),
    namereg: function(),
    resend: function(),
    sendIBANTransaction: function(),
    sendRawTransaction: function(),
    sendTransaction: function(),
    sign: function(),
    signTransaction: function(),
    submitTransaction: function(),
    submitWork: function()
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}
Step - 12

Create a variable called vehicle3_contract_txn to represent the contract transaction object, encapsulating the address of the dealer, the bytecode of the vehicle contract, and a gas price. Execute the following expression in the Javascript shell as shown below:

> var vehicle3_contract_txn = { from: dealer, data: '0x'+vehicle3.contracts['src/Vehicle3.sol:Vehicle3'].bin, gas: gas }

Check to ensure the variable vehicle3_contract_txn is initialized by executing the following command in the Javascript shell prompt:

> vehicle3_contract_txn

The following would be the typical output:

Output.14

{
  data: "0x6060604052341561000f57600080fd5b60405160a0806106a1833981016040528080519190602001805191906020018051919060200180519190602001805160008781556001879055600286905560038054600160a060020a03878116600160a060020a03199283161792839055600480543383169084161760a060020a60ff021916905560058054909216858216179091559294507f95220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bf9350909188918391166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1505050505061059b806101066000396000f3006060604052600436106100775763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634e69d560811461007c578063893d20e8146100b35780639cf6d1af146100e2578063a4e72902146100f5578063bd3e19d4146100ff578063bf20f94014610124575b600080fd5b341561008757600080fd5b61008f610137565b6040518082600181111561009f57fe5b60ff16815260200191505060405180910390f35b34156100be57600080fd5b6100c6610158565b604051600160a060020a03909116815260200160405180910390f35b34156100ed57600080fd5b6100c6610167565b6100fd610176565b005b341561010a57600080fd5b610112610543565b60405190815260200160405180910390f35b341561012f57600080fd5b610112610549565b60045474010000000000000000000000000000000000000000900460ff1690565b600354600160a060020a031690565b600454600160a060020a031690565b60008060025460015401600460009054906101000a9004600160a060020a03167fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60013484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a134829010156101fd57600080fd5b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60023484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1600354620f4240945034935033600160a060020a039081169116141561048c57600054600354600080516020610550833981519152916001918690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16004805474ff00000000000000000000000000000000000000001916740100000000000000000000000000000000000000001790819055600154600160a060020a039091169080156108fc0290604051600060405180830381858888f19350505050151561033a57600080fd5b600154600054600354919094039360008051602061055083398151915291600291908690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1600554600054600354600160a060020a039283169263cca10a219288928892166040517c010000000000000000000000000000000000000000000000000000000063ffffffff87160281526004810192909252600160a060020a031660248201526044016000604051808303818589803b151561041657600080fd5b88f1151561042357600080fd5b50506002546000546003805492909803976000805160206105508339815191529550935091508690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16104e4565b600054600354600080516020610550833981519152916004913490600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a15b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60033484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a150505050565b60015490565b60005490560095220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bfa165627a7a7230582031c62c3945703dc4333755b805a2120992c21af05e4cd84644a9e2b77c733b860029",
  from: "0x46bf8994c8702919434271d89bcad8abec915612",
  gas: 1000000
}
Step - 13

Now we are ready to deploy our Smart Contract for the vehicle called Vehicle3 into our private Ethereum network.

Since the contract will be deployed by the dealer account, we need to unlock the dealer account before proceeding further.

To unlock the dealer account, execute the following command in the Javascript shell prompt:

> personal.unlockAccount(dealer)

This will prompt us for the password for the dmv account. The following would be the typical output:

Output.15

Unlock account 0x46bf8994c8702919434271d89bcad8abec915612
Passphrase: dealer
true

Create a contract instance object called vehicle3_contract_inst, by calling the new method on the contract object vehicle3_contract, passing a constructor argument for the vin number (vin), the cost of the vehicle (cost), the processing fees (fees), the account address of the buyer (buyer), the contract address of the dmv Smart Contract (dmvregister_contract_addr), and the contract transaction object vehicle3_contract_txn. Execute the following command in the Javascript shell prompt:

> var vehicle3_contract_inst = vehicle3_contract.new(vin, cost, fees, buyer, dmvregister_contract_addr, vehicle3_contract_txn)

Check to ensure the variable vehicle3_contract_inst is initialized by executing the following command in the Javascript shell prompt:

> vehicle3_contract_inst

The following would be the typical output:

Output.16

{
  abi: [{
      constant: true,
      inputs: [],
      name: "getStatus",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getOwner",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getDealer",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: false,
      inputs: [],
      name: "buyVehicle",
      outputs: [],
      payable: true,
      stateMutability: "payable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getCost",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getVin",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      inputs: [{...}, {...}, {...}, {...}, {...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "constructor"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "BoughtEvt",
      type: "event"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "AmountEvt",
      type: "event"
  }],
  address: undefined,
  transactionHash: "0xd5dd939c3d03315a627fe226ede625f85a4d5fdc2023cd4b1defbe1995285748"
}
Step - 14

The above contract instance creation command will generate an Ethereum transaction that needs to be mined for the contract to be deployed into the private Blockchain network.

To check all the pending transactions, execute the following command in the Javascript shell prompt:

> eth.pendingTransactions

The following would be the typical output:

Output.17

[{
    blockHash: null,
    blockNumber: null,
    from: "0x46bf8994c8702919434271d89bcad8abec915612",
    gas: 1000000,
    gasPrice: 18000000000,
    hash: "0xd5dd939c3d03315a627fe226ede625f85a4d5fdc2023cd4b1defbe1995285748",
    input: "0x6060604052341561000f57600080fd5b60405160a0806106a1833981016040528080519190602001805191906020018051919060200180519190602001805160008781556001879055600286905560038054600160a060020a03878116600160a060020a03199283161792839055600480543383169084161760a060020a60ff021916905560058054909216858216179091559294507f95220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bf9350909188918391166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1505050505061059b806101066000396000f3006060604052600436106100775763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634e69d560811461007c578063893d20e8146100b35780639cf6d1af146100e2578063a4e72902146100f5578063bd3e19d4146100ff578063bf20f94014610124575b600080fd5b341561008757600080fd5b61008f610137565b6040518082600181111561009f57fe5b60ff16815260200191505060405180910390f35b34156100be57600080fd5b6100c6610158565b604051600160a060020a03909116815260200160405180910390f35b34156100ed57600080fd5b6100c6610167565b6100fd610176565b005b341561010a57600080fd5b610112610543565b60405190815260200160405180910390f35b341561012f57600080fd5b610112610549565b60045474010000000000000000000000000000000000000000900460ff1690565b600354600160a060020a031690565b600454600160a060020a031690565b60008060025460015401600460009054906101000a9004600160a060020a03167fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60013484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a134829010156101fd57600080fd5b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60023484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1600354620f4240945034935033600160a060020a039081169116141561048c57600054600354600080516020610550833981519152916001918690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16004805474ff00000000000000000000000000000000000000001916740100000000000000000000000000000000000000001790819055600154600160a060020a039091169080156108fc0290604051600060405180830381858888f19350505050151561033a57600080fd5b600154600054600354919094039360008051602061055083398151915291600291908690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a1600554600054600354600160a060020a039283169263cca10a219288928892166040517c010000000000000000000000000000000000000000000000000000000063ffffffff87160281526004810192909252600160a060020a031660248201526044016000604051808303818589803b151561041657600080fd5b88f1151561042357600080fd5b50506002546000546003805492909803976000805160206105508339815191529550935091508690600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a16104e4565b600054600354600080516020610550833981519152916004913490600160a060020a03166040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a15b7fa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c60033484846040519384526020840192909252604080840191909152600160a060020a0390911660608301526080909101905180910390a150505050565b60015490565b60005490560095220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bfa165627a7a7230582031c62c3945703dc4333755b805a2120992c21af05e4cd84644a9e2b77c733b86002900000000000000000000000000000000000000000000000000000000499602d20000000000000000000000000000000000000000000000003782dace9d9000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000035ddac855e0029676f489dafca9ab405a348317c0000000000000000000000001727b37a8a3334d62b5f669423a74517d18b9aeb",
    nonce: 0,
    r: "0x7a63a6413f3b2ccdba4fcb9446e2a23e6de1a4151d89ed0fb6367c5ba0a72928",
    s: "0x25f2b828c2a04b2d429efa26f5010d333dd55064958c2940a8018bae12a1694b",
    to: null,
    transactionIndex: 0,
    v: "0x4d",
    value: 0
}]

To start the miner with one thread, execute the following command in the Javascript shell prompt:

> miner.start(1)

Wait a few seconds (about 10 to 15 seconds) for the contract deployment transaction to be mined. The end result is that the contract will be deployed into our private Blockchain network.

Once the transaction is mined, we can stop the miner. Execute the following command in the Javascript shell prompt:

> miner.stop()

To retrieve the transaction details for the dmv contract deployment, execute the following command in the Javascript shell prompt:

> eth.getTransactionReceipt(vehicle3_contract_inst.transactionHash)

The following would be the typical output:

Output.18

{
  blockHash: "0x195f42065b8784552a306a5623f1fa608ecfc389c2b4b2a08aabdf4eefe5d52b",
  blockNumber: 6,
  contractAddress: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
  cumulativeGasUsed: 572400,
  from: "0x46bf8994c8702919434271d89bcad8abec915612",
  gasUsed: 572400,
  logs: [{
      address: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
      blockHash: "0x195f42065b8784552a306a5623f1fa608ecfc389c2b4b2a08aabdf4eefe5d52b",
      blockNumber: 6,
      data: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000499602d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035ddac855e0029676f489dafca9ab405a348317c",
      logIndex: 0,
      removed: false,
      topics: ["0x95220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bf"],
      transactionHash: "0xd5dd939c3d03315a627fe226ede625f85a4d5fdc2023cd4b1defbe1995285748",
      transactionIndex: 0
  }],
  logsBloom: "0x00000000000100000001000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000002000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x8474c4b84ca25450047f39ad6ee6b23337a8ed73dc6215e3ede705bc01060dda",
  to: null,
  transactionHash: "0xd5dd939c3d03315a627fe226ede625f85a4d5fdc2023cd4b1defbe1995285748",
  transactionIndex: 0
}

The presence of a value for the contractAddress (0xfa332003301955dd8526f0ef3aa7c670bda5f4fa) from the Output.17 indicates that the contract has been successfully deployed to our private Blockchain network.

Once again, let us display account balances using the Javascript utility function showBalances. Execute the following command in the Javascript shell prompt:

Before proceeding further, we will once again display the account balances. To display account balances using the Javascript utility function showBalances, execute the following command in the Javascript shell prompt:

> showBalances()

The following would be the typical output:

Output.19

---> eth.accounts[0]: 0xef17ec5df3116dea3b7abaf1ff3045639453cc76   balance: 90.017449272 ether
---> eth.accounts[1]: 0x35ddac855e0029676f489dafca9ab405a348317c  balance: 10 ether
---> eth.accounts[2]: 0x46bf8994c8702919434271d89bcad8abec915612  balance: 4.9896968 ether
---> eth.accounts[3]: 0x518a6377a3863201aef3310da41f3448d959a310  balance: 2.992853928 ether
undefined

Since the dealer deployed the contract Vehicle3 into our private Blockchain, as expected, the dealer account incurred a small processing fees in the form of gas.

Step - 15

Define a variable called vehicle3_contract_addr that is initialized with the value of the deployed vehicle contract address. Execute the following statement in the Javascript shell as shown below:

> var vehicle3_contract_addr = eth.getTransactionReceipt(vehicle3_contract_inst.transactionHash).contractAddress

To check the value of the contract transaction object variable vehicle3_contract_addr, execute the following command in the Javascript shell prompt:

Check to ensure the variable vehicle3_contract_addr is initialized by executing the following command in the Javascript shell prompt:

> vehicle3_contract_addr

The following would be the typical output:

Output.20

"0xfa332003301955dd8526f0ef3aa7c670bda5f4fa"
Step - 16

To interact (invoke functions) with the deployed Vehicle3 contract, we need an instance of the contract. To create an instance of the Vehicle3 contract, invoke the at method on the contract object vehicle3_contract, passing in the value of the variable vehicle3_contract_addr as an argument. Execute the following command in the Javascript shell prompt:

> var vehicle3_obj = vehicle3_contract.at(vehicle3_contract_addr)

To check the value of the contract instance variable vehicle3_obj, execute the following command in the Javascript shell prompt:

> vehicle3_obj

The following would be the typical output:

Output.21

{
  abi: [{
      constant: true,
      inputs: [],
      name: "getStatus",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getOwner",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getDealer",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: false,
      inputs: [],
      name: "buyVehicle",
      outputs: [],
      payable: true,
      stateMutability: "payable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getCost",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "getVin",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }, {
      inputs: [{...}, {...}, {...}, {...}, {...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "constructor"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "BoughtEvt",
      type: "event"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}, {...}],
      name: "AmountEvt",
      type: "event"
  }],
  address: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
  transactionHash: null,
  AmountEvt: function(),
  BoughtEvt: function(),
  allEvents: function(),
  buyVehicle: function(),
  getCost: function(),
  getDealer: function(),
  getOwner: function(),
  getStatus: function(),
  getVin: function()
}

Before proceeding further, let us verify the license number associated with the vehicle vin number. Remember, that the buyer has not yet initiated any transaction on the deployed vehicle contract, and hence there should not be any valid license number associated with the vin. Invoke the getLicense method on the dmv contract instance dmvregister_obj by executing the following command in the Javascript shell prompt:

> dmvregister_obj.getLicense(vin)

The following would be the typical output:

Output.22

0

From the Output.22 above, it is clear that there is no valid license number assigned to the specified vin yet.

Step - 17

The buyer will send a transaction message to invoke the method buyVehicle on the object vehicle3_obj, along with a payment covering the total cost for the vehicle (cost + fees).

Define a variable called buyer_txn to represent the transaction message that encapsulates the address of the buyer (buyer), the total cost of the vehicle (total), and the gas price (gas). Execute the following statement in the Javascript shell as shown below:

> var buyer_txn = { from: buyer, value: total, gas: gas }

To check the value of the variable buyer_txn, execute the following command in the Javascript shell prompt:

> buyer_txn

The following would be the typical output:

Output.23

{
  from: "0x35ddac855e0029676f489dafca9ab405a348317c",
  gas: 1000000,
  value: 5000000000000000000
}

Since the buyer is initiating the transaction, we need to unlock the buyer account before proceeding further.

To unlock the buyer account, execute the following command in the Javascript shell prompt:

> personal.unlockAccount(buyer)

This will prompt us for the password for the buyer account. The following would be the typical output:

Output.24

Unlock account 0x35ddac855e0029676f489dafca9ab405a348317c
Passphrase: buyer
true

The buyer will activate the contract by calling the sendTransaction method on the object vehicle3_obj.buyVehicle. Execute the following command in the Javascript shell prompt:

> var buyer_txn_hash = vehicle3_obj.buyVehicle.sendTransaction(buyer_txn)

Check the value of the variable buyer_txn_hash that represents the transaction hash by executing the following command in the Javascript shell prompt:

> buyer_txn_hash

The following would be the typical output:

Output.25

"0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396"

The transaction created by the buyer needs to be mined in order to trigger the method invocation on the deployed contract on our private Blockchain network.

To check all the pending transactions, execute the following command in the Javascript shell prompt:

> eth.pendingTransactions

The following would be the typical output:

Output.26

[{
    blockHash: null,
    blockNumber: null,
    from: "0x35ddac855e0029676f489dafca9ab405a348317c",
    gas: 1000000,
    gasPrice: 18000000000,
    hash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
    input: "0xa4e72902",
    nonce: 0,
    r: "0x73c53ba5375edc4e13c39d88e1001a4a3ed924710382432d80d85b71726666bf",
    s: "0x142f1483e475c06432ba25dab883bdf7cdd21abe663e15810a0d6f9a83eceb04",
    to: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
    transactionIndex: 0,
    v: "0x4d",
    value: 5000000000000000000
}]

To start the miner with one thread, execute the following command in the Javascript shell prompt:

> miner.start(1)

Wait a few seconds (about 10 to 15 seconds) for the buyer transaction message to be mined. The end result is that the contract method vehicle3_obj.buyVehicle will be invoked, executing the logic in the method.

Once the transaction is mined, we can stop the miner. Execute the following command in the Javascript shell prompt:

> miner.stop()

To retrieve the transaction details for the buyer contract execution, execute the following command in the Javascript shell prompt:

> eth.getTransactionReceipt(buyer_txn_hash)

The following would be the typical output:

Output.27

{
  blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
  blockNumber: 15,
  contractAddress: null,
  cumulativeGasUsed: 144400,
  from: "0x35ddac855e0029676f489dafca9ab405a348317c",
  gasUsed: 144400,
  logs: [{
      address: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000046bf8994c8702919434271d89bcad8abec915612",
      logIndex: 0,
      removed: false,
      topics: ["0xa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000046bf8994c8702919434271d89bcad8abec915612",
      logIndex: 1,
      removed: false,
      topics: ["0xa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000499602d20000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000035ddac855e0029676f489dafca9ab405a348317c",
      logIndex: 2,
      removed: false,
      topics: ["0x95220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bf"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000499602d20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000035ddac855e0029676f489dafca9ab405a348317c",
      logIndex: 3,
      removed: false,
      topics: ["0x95220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bf"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0x1727b37a8a3334d62b5f669423a74517d18b9aeb",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000518a6377a3863201aef3310da41f3448d959a310",
      logIndex: 4,
      removed: false,
      topics: ["0xa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0x1727b37a8a3334d62b5f669423a74517d18b9aeb",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000518a6377a3863201aef3310da41f3448d959a310",
      logIndex: 5,
      removed: false,
      topics: ["0xa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0x1727b37a8a3334d62b5f669423a74517d18b9aeb",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000499602d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000035ddac855e0029676f489dafca9ab405a348317c",
      logIndex: 6,
      removed: false,
      topics: ["0xd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e6"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0x1727b37a8a3334d62b5f669423a74517d18b9aeb",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000499602d20000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035ddac855e0029676f489dafca9ab405a348317c",
      logIndex: 7,
      removed: false,
      topics: ["0xd48742c718bff6639d660fdc7ee2490144cec186cbc6e2672aad33b0d7c7f1e6"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0x1727b37a8a3334d62b5f669423a74517d18b9aeb",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000518a6377a3863201aef3310da41f3448d959a310",
      logIndex: 8,
      removed: false,
      topics: ["0xa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000499602d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035ddac855e0029676f489dafca9ab405a348317c",
      logIndex: 9,
      removed: false,
      topics: ["0x95220c63110cc8cabcb0e392391cb923d89015bec2afbb6e668d8f463dd8c9bf"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }, {
      address: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
      blockHash: "0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99",
      blockNumber: 15,
      data: "0x00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000046bf8994c8702919434271d89bcad8abec915612",
      logIndex: 10,
      removed: false,
      topics: ["0xa6eeda949aa9e928463d0850d41fb5d526023dabcf145aeca26f46853246cf2c"],
      transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
      transactionIndex: 0
  }],
  logsBloom: "0x00000000000100000201000000000000000000000000000000000020000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000002000010000000000000000000000000000000000000000000000208000000000000000002000000000000000000000000000001000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x3bba2970db1e2b7ab52b03e434ad1b29a9da80e965ff7e9409f95f480b04c601",
  to: "0xfa332003301955dd8526f0ef3aa7c670bda5f4fa",
  transactionHash: "0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396",
  transactionIndex: 0
}

Once again, let us display account balances using the Javascript utility function showBalances. Execute the following command in the Javascript shell prompt:

Before proceeding further, we will once again display the account balances. To display account balances using the Javascript utility function showBalances, execute the following command in the Javascript shell prompt:

> showBalances()

The following would be the typical output:

Output.28

---> eth.accounts[0]: 0xef17ec5df3116dea3b7abaf1ff3045639453cc76   balance: 105.020048472 ether
---> eth.accounts[1]: 0x35ddac855e0029676f489dafca9ab405a348317c  balance: 4.9974008 ether
---> eth.accounts[2]: 0x46bf8994c8702919434271d89bcad8abec915612  balance: 8.9896968 ether
---> eth.accounts[3]: 0x518a6377a3863201aef3310da41f3448d959a310  balance: 3.992853928 ether
undefined

Comparing Output.26 to Output.18, we see the account balance of the dealer has increased by 4 ethers and the account balance of the dmv has increased by an ether.

Once again, let us verify the license number associated with the vehicle vin number. Invoke the getLicense method on the dmv contract instance dmvregister_obj by executing the following command in the Javascript shell prompt:

> dmvregister_obj.getLicense(vin)

The following would be the typical output:

Output.29

101

BINGO !!! This time around, from the Output.29 above, we see a valid license number assigned to the specified vin number.

Step - 18

To display all the events emitted during the invocation of the method vehicle3_obj.buyVehicle, we need to create an instance of the allEvents filter. We then invoke the watch method on the filter instance, specifying a callback function to display the event details.

To create a filter instance for all events, execute the following command in the Javascript shell prompt:

> var vehicle3_events = vehicle3_obj.allEvents({fromBlock: 0, toBlock: 'latest'})

We want to scan the transaction log(s) for all the mined blocks, and hence the fromBlock of 0 to the toBlock of latest.

To start the display of event(s) from the transaction log(s), execute the following command in the Javascript shell prompt:

> var dummy = vehicle3_events.watch(function (error, result) { console.log("=> " + JSON.stringify(result)); })

The following would be the typical output:

Output.30

=> {"address":"0xfa332003301955dd8526f0ef3aa7c670bda5f4fa","args":{"buyer":"0x35ddac855e0029676f489dafca9ab405a348317c","flag":"0","value":"0","vin":"1234567890"},"blockHash":"0x195f42065b8784552a306a5623f1fa608ecfc389c2b4b2a08aabdf4eefe5d52b","blockNumber":6,"event":"BoughtEvt","logIndex":0,"removed":false,"transactionHash":"0xd5dd939c3d03315a627fe226ede625f85a4d5fdc2023cd4b1defbe1995285748","transactionIndex":0}
=> {"address":"0xfa332003301955dd8526f0ef3aa7c670bda5f4fa","args":{"amount":"5000000000000000000","context":"0x46bf8994c8702919434271d89bcad8abec915612","flag":"1","value":"5000000000000000000"},"blockHash":"0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99","blockNumber":15,"event":"AmountEvt","logIndex":0,"removed":false,"transactionHash":"0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396","transactionIndex":0}
=> {"address":"0xfa332003301955dd8526f0ef3aa7c670bda5f4fa","args":{"amount":"5000000000000000000","context":"0x46bf8994c8702919434271d89bcad8abec915612","flag":"2","value":"5000000000000000000"},"blockHash":"0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99","blockNumber":15,"event":"AmountEvt","logIndex":1,"removed":false,"transactionHash":"0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396","transactionIndex":0}
=> {"address":"0xfa332003301955dd8526f0ef3aa7c670bda5f4fa","args":{"buyer":"0x35ddac855e0029676f489dafca9ab405a348317c","flag":"1","value":"5000000000000000000","vin":"1234567890"},"blockHash":"0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99","blockNumber":15,"event":"BoughtEvt","logIndex":2,"removed":false,"transactionHash":"0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396","transactionIndex":0}
=> {"address":"0xfa332003301955dd8526f0ef3aa7c670bda5f4fa","args":{"buyer":"0x35ddac855e0029676f489dafca9ab405a348317c","flag":"2","value":"1000000000000000000","vin":"1234567890"},"blockHash":"0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99","blockNumber":15,"event":"BoughtEvt","logIndex":3,"removed":false,"transactionHash":"0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396","transactionIndex":0}
=> {"address":"0xfa332003301955dd8526f0ef3aa7c670bda5f4fa","args":{"buyer":"0x35ddac855e0029676f489dafca9ab405a348317c","flag":"3","value":"0","vin":"1234567890"},"blockHash":"0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99","blockNumber":15,"event":"BoughtEvt","logIndex":9,"removed":false,"transactionHash":"0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396","transactionIndex":0}
=> {"address":"0xfa332003301955dd8526f0ef3aa7c670bda5f4fa","args":{"amount":"5000000000000000000","context":"0x46bf8994c8702919434271d89bcad8abec915612","flag":"3","value":"5000000000000000000"},"blockHash":"0x9449fd8223aeebe8548f534b8f104fac759725e5fad7a60e61f3ae78452b8e99","blockNumber":15,"event":"AmountEvt","logIndex":10,"removed":false,"transactionHash":"0x7c5b7485d4ff37f2eea7853f65d60ea266e3375121b1d66a08bfc2d224ecb396","transactionIndex":0}
undefined

To stop the event watcher, execute the following command in the Javascript shell prompt:

> vehicle3_events.stopWatching()

YIPEE !!! We have successfully demonstrated the end-to-end use-case for the simple vehicle buying use-case (involving the buyer, the dealer, and the dmv) as laid out in our first introductory article.

References

Introduction to Ethereum - Part 3

Introduction to Ethereum - Part 2

Introduction to Ethereum - Part 1

Introduction to Blockchain