Blockchain: Contracts and AddressesWith an Ethereum contract we can reuse it by sharing its address. Let's setup a marriage contract. pragma solidity ^0.4.0; contract Marriage { // Marriage data variables address public owner; bytes32 public partner1; bytes32 public partner2; uint256 public marriageDate; bytes32 public marriageStatus; bytes public imageHash; bytes public marriageProofDoc; //Set Owner function Marriage() { owner = msg.sender; } modifier onlyowner() { if (msg.sender == owner) _; } // Create initial marriage contract function createMarriage(bytes32 partner1Entry, bytes32 partner2Entry, uint256 marriageDateEntry, bytes32 statusEntry, bytes32 descriptionEntry) onlyowner { partner1 = partner1Entry; partner2 = partner2Entry; marriageDate = marriageDateEntry; setStatus(statusEntry); bytes32 name = "Marriage Contract Creation"; majorEventFunc(marriageDate, name, descriptionEntry); } function getOwner() returns(address owner) { return owner; } // Set the marriage status if it changes function setStatus(bytes32 status) onlyowner { marriageStatus = status; majorEventFunc(block.timestamp, "Changed Status", status); } // Set the IPFS hash of the image of the couple function setImage(bytes IPFSImageHash) onlyowner { imageHash = IPFSImageHash; majorEventFunc(block.timestamp, "Entered Marriage Image", "Image is in IPFS"); } // Upload documentation for proof of marrage like a marriage certificate function marriageProof(bytes IPFSProofHash) onlyowner { marriageProofDoc = IPFSProofHash; majorEventFunc(block.timestamp, "Entered Marriage Proof", "Marriage proof in IPFS"); } // Log major life events function majorEventFunc(uint256 eventTimeStamp, bytes32 name, bytes32 description) { MajorEvent(block.timestamp, eventTimeStamp, name, description); } // Declare event structure event MajorEvent(uint256 logTimeStamp, uint256 eventTimeStamp, bytes32 indexed name, bytes32 indexed description); // This function gets executed if a transaction with invalid data is sent to // the contract or just ether without data. We revert the send so that no-one // accidentally loses money when using the contract. function() { throw; } } This is then compiled into:
var browser_marriage_sol_marriageContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"partner1Entry","type":"bytes32"},{"name":"partner2Entry","type":"bytes32"},{"name":"marriageDateEntry","type":"uint256"},{"name":"statusEntry","type":"bytes32"},{"name":"descriptionEntry","type":"bytes32"}],"name":"createMarriage","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"status","type":"bytes32"}],"name":"setStatus","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"IPFSImageHash","type":"bytes"}],"name":"setImage","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"marriageDate","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"imageHash","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"getOwner","outputs":[{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"partner2","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"partner1","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"marriageProofDoc","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"marriageStatus","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"IPFSProofHash","type":"bytes"}],"name":"marriageProof","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"eventTimeStamp","type":"uint256"},{"name":"name","type":"bytes32"},{"name":"description","type":"bytes32"}],"name":"majorEventFunc","outputs":[],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"payable":false,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"logTimeStamp","type":"uint256"},{"indexed":false,"name":"eventTimeStamp","type":"uint256"},{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"description","type":"bytes32"}],"name":"MajorEvent","type":"event"}]);
var browser_marriage_sol_marriage = browser_marriage_sol_marriageContract.new(
{
from: web3.eth.accounts[0],
data: '0x606...96326a70029',
gas: '4000000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
Now let's create the contract and mine it: > personal.unlockAccount(web3.eth.accounts[0],'Qwerty') true > loadScript('marriage.js') null [object Object] true > null [object Object] Contract mined! address: 0x5c74af4ee2e0a8c0dba5f344f17b03c2ffb37d9d transactionH ash: 0x3381c4af50f6d2359b2b09d288fc331657e908451a99336c07ec4a45664b7276 > miner.stop() true > browser_marriage_sol_marriage { abi: [{ constant: false, inputs: [{...}, {...}, {...}, {...}, {...}], name: "createMarriage", outputs: [], payable: false, type: "function" }, { constant: false, inputs: [{...}], name: "setStatus", outputs: [], payable: false, type: "function" }, { constant: false, inputs: [{...}], name: "setImage", outputs: [], payable: false, type: "function" }, { constant: true, inputs: [], name: "marriageDate", outputs: [{...}], payable: false, type: "function" }, { constant: true, inputs: [], name: "imageHash", outputs: [{...}], payable: false, type: "function" }, { constant: false, inputs: [], name: "getOwner", outputs: [{...}], payable: false, type: "function" }, { constant: true, inputs: [], name: "partner2", outputs: [{...}], payable: false, type: "function" }, { constant: true, inputs: [], name: "owner", outputs: [{...}], payable: false, type: "function" }, { constant: true, inputs: [], name: "partner1", outputs: [{...}], payable: false, type: "function" }, { constant: true, inputs: [], name: "marriageProofDoc", outputs: [{...}], payable: false, type: "function" }, { constant: true, inputs: [], name: "marriageStatus", outputs: [{...}], payable: false, type: "function" }, { constant: false, inputs: [{...}], name: "marriageProof", outputs: [], payable: false, type: "function" }, { constant: false, inputs: [{...}, {...}, {...}], name: "majorEventFunc", outputs: [], payable: false, type: "function" }, { inputs: [], payable: false, type: "constructor" }, { payable: false, type: "fallback" }, { anonymous: false, inputs: [{...}, {...}, {...}, {...}], name: "MajorEvent", type: "event" }], address: "0x5c74af4ee2e0a8c0dba5f344f17b03c2ffb37d9d", transactionHash: "0x3381c4af50f6d2359b2b09d288fc331657e908451a99336c07ec4a45664b7276", MajorEvent: function(), allEvents: function(), createMarriage: function(), getOwner: function(), imageHash: function(), majorEventFunc: function(), marriageDate: function(), marriageProof: function(), marriageProofDoc: function(), marriageStatus: function(), owner: function(), partner1: function(), partner2: function(), setImage: function(), setStatus: function() } > browser_marriage_sol_marriage.createMarriage() Error: invalid address at web3.js:3879:15 at web3.js:3705:20 at web3.js:4948:28 at map (native code) at web3.js:4947:12 at web3.js:4973:18 at web3.js:4998:23 at web3.js:4061:16 at apply (native code) at web3.js:4147:16 > web3.eth.defaultAccount =web3.eth.accounts[0] "0xc7552f45deb093cafb47286a0bc9415845ca3735" Now let's create a new marriage: > personal.unlockAccount(web3.eth.accounts[0],'Qwerty') true > browser_marriage_sol_marriage.createMarriage('James','Linda') "0xac265552396b4c19ae54766c130f3a56052a2e512fcbd43a2d10197faf6ff8c6" > miner.start() null > miner.stop() true > eth.getTransaction("0xac265552396b4c19ae54766c130f3a56052a2e512fcbd43a2d10197faf6ff8c6") { blockHash: "0xc5b04c0253b5cced20d1df81f8f3f745ea8ea09e49a9a20889582992688923fc", blockNumber: 5479, from: "0xc7552f45deb093cafb47286a0bc9415845ca3735", gas: 90000, gasPrice: 18000000000, hash: "0xac265552396b4c19ae54766c130f3a56052a2e512fcbd43a2d10197faf6ff8c6", input: "0x1158f6964a616d657300000000000000000000000000000000000000000000000000 00004c696e6461000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000", nonce: 90, r: "0x18effe6d9c512e881477c20719544ada0ee61e97bafce0915cc5b19763d06742", s: "0x49e4d165e13168ccee78c70de00bd98024aa69ae5e0295dffe1b774b4cd5a12c", to: "0x5c74af4ee2e0a8c0dba5f344f17b03c2ffb37d9d", transactionIndex: 0, v: "0x41", value: 0 } In this case "James" is 4a 61 6d 65 73 and Linda is 4c 69 6e 64 61 Now, once we have the contract, we can get others to use it by sending the address. In this case we can see that the address is: address: "0x5c74af4ee2e0a8c0dba5f344f17b03c2ffb37d9d", Now let's create a new marriage record: var browser_marriage_sol_marriageContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"partner1Entry","type":"bytes32"},{"name":"partner2Entry","type":"bytes32"},{"name":"marriageDateEntry","type":"uint256"},{"name":"statusEntry","type":"bytes32"},{"name":"descriptionEntry","type":"bytes32"}],"name":"createMarriage","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"status","type":"bytes32"}],"name":"setStatus","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"IPFSImageHash","type":"bytes"}],"name":"setImage","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"marriageDate","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"imageHash","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"getOwner","outputs":[{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"partner2","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"partner1","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"marriageProofDoc","outputs":[{"name":"","type":"bytes"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"marriageStatus","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"IPFSProofHash","type":"bytes"}],"name":"marriageProof","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"eventTimeStamp","type":"uint256"},{"name":"name","type":"bytes32"},{"name":"description","type":"bytes32"}],"name":"majorEventFunc","outputs":[],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"payable":false,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"logTimeStamp","type":"uint256"},{"indexed":false,"name":"eventTimeStamp","type":"uint256"},{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"description","type":"bytes32"}],"name":"MajorEvent","type":"event"}]); var browser_marriage_sol_marriage = browser_marriage_sol_marriageContract.at("0x5c74af4ee2e0a8c0dba5f344f17b03c2ffb37d9d"); We can now create a new marriage record: > browser_marriage_sol_marriage.createMarriage('John','Mandy') "0xa4bb8d3d9792519bb83113b08ef2aafcb0e5745675cf03b664953d554f30991c" > miner.start() > miner.stop() Now we can view: > web3.eth.getTransaction("0xa4bb8d3d9792519bb83113b08ef2aafcb0e5745675cf03b664953d554f30991c") { blockHash: "0xc64469f36937648c45fec324709a84ff40ca52044583548f69cc21d759d92faf", blockNumber: 5486, from: "0xc7552f45deb093cafb47286a0bc9415845ca3735", gas: 90000, gasPrice: 18000000000, hash: "0xa4bb8d3d9792519bb83113b08ef2aafcb0e5745675cf03b664953d554f30991c", input: "0x1158f6964a6f686e0000000000000000000000000000000000000000000000000000 00004d616e6479000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000", nonce: 91, r: "0xa498e85b3033a04e106e2da9bd9ab50da2ee687da8a0c50148ce1eb160ab875c", s: "0x6b73d36837640bc1f09a992fda3c2ef629722d9db8e0f5cec80e64614191c547", to: "0x5c74af4ee2e0a8c0dba5f344f17b03c2ffb37d9d", transactionIndex: 0, v: "0x41", value: 0 } |