├── .gitignore ├── metacoin ├── test │ ├── .placeholder │ ├── TestMetacoin.sol │ ├── metacoin_2.js │ └── metacoin.js ├── contracts │ ├── .placeholder │ ├── ConvertLib.sol │ ├── Migrations.sol │ └── MetaCoin.sol ├── truffle.js ├── truffle-config.js └── migrations │ ├── 1_initial_migration.js │ └── 2_deploy_contracts.js ├── truffle ├── truffle.js ├── truffle-config.js ├── migrations │ └── 1_initial_migration.js └── contracts │ └── Migrations.sol ├── package.json ├── metamask_example ├── index.html ├── script.js └── publish.js ├── metamask_template ├── index.html └── script.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /metacoin/test/.placeholder: -------------------------------------------------------------------------------- 1 | This is a placeholder file to ensure the parent directory in the git repository. Feel free to remove. 2 | -------------------------------------------------------------------------------- /metacoin/contracts/.placeholder: -------------------------------------------------------------------------------- 1 | This is a placeholder file to ensure the parent directory in the git repository. Feel free to remove. 2 | -------------------------------------------------------------------------------- /metacoin/truffle.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // See 3 | // to customize your Truffle configuration! 4 | }; 5 | -------------------------------------------------------------------------------- /truffle/truffle.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // See 3 | // to customize your Truffle configuration! 4 | }; 5 | -------------------------------------------------------------------------------- /metacoin/truffle-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // See 3 | // to customize your Truffle configuration! 4 | }; 5 | -------------------------------------------------------------------------------- /truffle/truffle-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // See 3 | // to customize your Truffle configuration! 4 | }; 5 | -------------------------------------------------------------------------------- /metacoin/migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /truffle/migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /metacoin/contracts/ConvertLib.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.4; 2 | 3 | library ConvertLib{ 4 | function convert(uint amount,uint conversionRate) public pure returns (uint convertedAmount) 5 | { 6 | return amount * conversionRate; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /metacoin/migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | var ConvertLib = artifacts.require("./ConvertLib.sol"); 2 | var MetaCoin = artifacts.require("./MetaCoin.sol"); 3 | 4 | module.exports = function(deployer) { 5 | deployer.deploy(ConvertLib); 6 | deployer.link(ConvertLib, MetaCoin); 7 | deployer.deploy(MetaCoin); 8 | }; 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web3_demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "ganache-cli": "^6.0.3", 13 | "truffle": "^4.0.6", 14 | "web3": "^0.20.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /metamask_example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Hello!


8 | 9 |
10 |
11 |
12 |
13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /metamask_template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Hello!


8 | 9 |
10 |
11 |
12 |
13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /metacoin/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.2; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | modifier restricted() { 8 | if (msg.sender == owner) _; 9 | } 10 | 11 | function Migrations() public { 12 | owner = msg.sender; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /truffle/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.17; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | modifier restricted() { 8 | if (msg.sender == owner) _; 9 | } 10 | 11 | function Migrations() public { 12 | owner = msg.sender; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /metacoin/test/TestMetacoin.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.2; 2 | 3 | import "truffle/Assert.sol"; 4 | import "truffle/DeployedAddresses.sol"; 5 | import "../contracts/MetaCoin.sol"; 6 | 7 | contract TestMetacoin { 8 | 9 | function testInitialBalanceUsingDeployedContract() public { 10 | MetaCoin meta = MetaCoin(DeployedAddresses.MetaCoin()); 11 | 12 | uint expected = 10000; 13 | 14 | Assert.equal(meta.getBalance(tx.origin), expected, "Owner should have 10000 MetaCoin initially"); 15 | } 16 | 17 | function testInitialBalanceWithNewMetaCoin() public { 18 | MetaCoin meta = new MetaCoin(); 19 | 20 | uint expected = 10000; 21 | 22 | Assert.equal(meta.getBalance(tx.origin), expected, "Owner should have 10000 MetaCoin initially"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /metacoin/contracts/MetaCoin.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "./ConvertLib.sol"; 4 | 5 | // This is just a simple example of a coin-like contract. 6 | // It is not standards compatible and cannot be expected to talk to other 7 | // coin/token contracts. If you want to create a standards-compliant 8 | // token, see: https://github.com/ConsenSys/Tokens. Cheers! 9 | 10 | contract MetaCoin { 11 | mapping (address => uint) balances; 12 | 13 | event Transfer(address indexed _from, address indexed _to, uint256 _value); 14 | 15 | function MetaCoin() public { 16 | balances[tx.origin] = 10000; 17 | } 18 | 19 | function sendCoin(address receiver, uint amount) public returns(bool sufficient) { 20 | if (balances[msg.sender] < amount) return false; 21 | balances[msg.sender] -= amount; 22 | balances[receiver] += amount; 23 | Transfer(msg.sender, receiver, amount); 24 | return true; 25 | } 26 | 27 | function getBalanceInEth(address addr) public view returns(uint){ 28 | return ConvertLib.convert(getBalance(addr),2); 29 | } 30 | 31 | function getBalance(address addr) public view returns(uint) { 32 | return balances[addr]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /metamask_template/script.js: -------------------------------------------------------------------------------- 1 | //this function will be called when the whole page is loaded 2 | window.onload = function(){ 3 | if (typeof web3 === 'undefined') { 4 | //if there is no web3 variable 5 | displayMessage("Error! Are you sure that you are using metamask?"); 6 | } else { 7 | displayMessage("Welcome to our DAPP!"); 8 | init(); 9 | } 10 | } 11 | 12 | var contractInstance; 13 | 14 | var abi = []; //TODO 15 | 16 | var address = ""; //TODO 17 | var acc; 18 | 19 | function init(){ 20 | var Contract = web3.eth.contract(abi); 21 | contractInstance = Contract.at(address); 22 | updateAccount(); 23 | } 24 | 25 | function updateAccount(){ 26 | //in metamask, the accounts array is of size 1 and only contains the currently selected account. The user can select a different account and so we need to update our account variable 27 | acc = web3.eth.accounts[0]; 28 | } 29 | 30 | function displayMessage(message){ 31 | var el = document.getElementById("message"); 32 | el.innerHTML = message; 33 | } 34 | 35 | function getTextInput(){ 36 | var el = document.getElementById("input"); 37 | 38 | return el.value; 39 | } 40 | 41 | function onButtonPressed(){ 42 | updateAccount(); 43 | 44 | //TODO 45 | } 46 | 47 | function onSecondButtonPressed(){ 48 | updateAccount(); 49 | 50 | //TODO 51 | } 52 | -------------------------------------------------------------------------------- /metacoin/test/metacoin_2.js: -------------------------------------------------------------------------------- 1 | const MetaCoin = artifacts.require("MetaCoin"); 2 | 3 | contract('2nd MetaCoin test', async (accounts) => { 4 | 5 | it("should put 10000 MetaCoin in the first account", async () => { 6 | let instance = await MetaCoin.deployed(); 7 | let balance = await instance.getBalance.call(accounts[0]); 8 | assert.equal(balance.valueOf(), 10000); 9 | }) 10 | 11 | it("should call a function that depends on a linked library", async () => { 12 | let meta = await MetaCoin.deployed(); 13 | let outCoinBalance = await meta.getBalance.call(accounts[0]); 14 | let metaCoinBalance = outCoinBalance.toNumber(); 15 | let outCoinBalanceEth = await meta.getBalanceInEth.call(accounts[0]); 16 | let metaCoinEthBalance = outCoinBalanceEth.toNumber(); 17 | assert.equal(metaCoinEthBalance, 2 * metaCoinBalance); 18 | 19 | }); 20 | 21 | it("should send coin correctly", async () => { 22 | 23 | // Get initial balances of first and second account. 24 | let account_one = accounts[0]; 25 | let account_two = accounts[1]; 26 | 27 | let amount = 10; 28 | 29 | 30 | let instance = await MetaCoin.deployed(); 31 | let meta = instance; 32 | 33 | let balance = await meta.getBalance.call(account_one); 34 | let account_one_starting_balance = balance.toNumber(); 35 | 36 | balance = await meta.getBalance.call(account_two); 37 | let account_two_starting_balance = balance.toNumber(); 38 | await meta.sendCoin(account_two, amount, {from: account_one}); 39 | 40 | balance = await meta.getBalance.call(account_one); 41 | let account_one_ending_balance = balance.toNumber(); 42 | 43 | balance = await meta.getBalance.call(account_two); 44 | let account_two_ending_balance = balance.toNumber(); 45 | 46 | assert.equal(account_one_ending_balance, account_one_starting_balance - amount, "Amount wasn't correctly taken from the sender"); 47 | assert.equal(account_two_ending_balance, account_two_starting_balance + amount, "Amount wasn't correctly sent to the receiver"); 48 | }); 49 | 50 | }) -------------------------------------------------------------------------------- /metamask_example/script.js: -------------------------------------------------------------------------------- 1 | //this function will be called when the whole page is loaded 2 | window.onload = function(){ 3 | if (typeof web3 === 'undefined') { 4 | //if there is no web3 variable 5 | displayMessage("Error! Are you sure that you are using metamask?"); 6 | } else { 7 | displayMessage("Welcome to our DAPP!"); 8 | init(); 9 | } 10 | } 11 | 12 | var contractInstance; 13 | 14 | var abi = [{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]; 15 | 16 | var address = "0x4e72770760c011647d4873f60a3cf6cdea896cd8"; 17 | var acc; 18 | 19 | function init(){ 20 | var Contract = web3.eth.contract(abi); 21 | contractInstance = Contract.at(address); 22 | updateAccount(); 23 | } 24 | 25 | function updateAccount(){ 26 | //in metamask, the accounts array is of size 1 and only contains the currently selected account. The user can select a different account and so we need to update our account variable 27 | acc = web3.eth.accounts[0]; 28 | } 29 | 30 | function displayMessage(message){ 31 | var el = document.getElementById("message"); 32 | el.innerHTML = message; 33 | } 34 | 35 | function getTextInput(){ 36 | var el = document.getElementById("input"); 37 | 38 | return el.value; 39 | } 40 | 41 | function onButtonPressed(){ 42 | updateAccount(); 43 | 44 | var input = getTextInput(); 45 | 46 | contractInstance.transferOwnership(input, {"from": acc}, function(err, res){ 47 | if(!err){ 48 | displayMessage("Success! Transaction hash: " + res.valueOf()); 49 | } else { 50 | displayMessage("Something went wrong. Are you sure that you are the current owner?"); 51 | } 52 | }); 53 | } 54 | 55 | function onSecondButtonPressed(){ 56 | updateAccount(); 57 | 58 | contractInstance.owner.call({"from": acc}, function(err, res) { 59 | if(!err){ 60 | displayMessage("The current owner is " + res.valueOf()); 61 | } else { 62 | displayMessage("Something went horribly wrong. Deal with it:", err); 63 | } 64 | }); 65 | } 66 | -------------------------------------------------------------------------------- /metacoin/test/metacoin.js: -------------------------------------------------------------------------------- 1 | var MetaCoin = artifacts.require("MetaCoin"); 2 | 3 | contract('MetaCoin', function(accounts) { 4 | it("should put 10000 MetaCoin in the first account", function() { 5 | return MetaCoin.deployed().then(function(instance) { 6 | return instance.getBalance.call(accounts[0]); 7 | }).then(function(balance) { 8 | assert.equal(balance.valueOf(), 10000, "10000 wasn't in the first account"); 9 | }); 10 | }); 11 | it("should call a function that depends on a linked library", function() { 12 | var meta; 13 | var metaCoinBalance; 14 | var metaCoinEthBalance; 15 | 16 | return MetaCoin.deployed().then(function(instance) { 17 | meta = instance; 18 | return meta.getBalance.call(accounts[0]); 19 | }).then(function(outCoinBalance) { 20 | metaCoinBalance = outCoinBalance.toNumber(); 21 | return meta.getBalanceInEth.call(accounts[0]); 22 | }).then(function(outCoinBalanceEth) { 23 | metaCoinEthBalance = outCoinBalanceEth.toNumber(); 24 | }).then(function() { 25 | assert.equal(metaCoinEthBalance, 2 * metaCoinBalance, "Library function returned unexpected function, linkage may be broken"); 26 | }); 27 | }); 28 | it("should send coin correctly", function() { 29 | var meta; 30 | 31 | // Get initial balances of first and second account. 32 | var account_one = accounts[0]; 33 | var account_two = accounts[1]; 34 | 35 | var account_one_starting_balance; 36 | var account_two_starting_balance; 37 | var account_one_ending_balance; 38 | var account_two_ending_balance; 39 | 40 | var amount = 10; 41 | 42 | return MetaCoin.deployed().then(function(instance) { 43 | meta = instance; 44 | return meta.getBalance.call(account_one); 45 | }).then(function(balance) { 46 | account_one_starting_balance = balance.toNumber(); 47 | return meta.getBalance.call(account_two); 48 | }).then(function(balance) { 49 | account_two_starting_balance = balance.toNumber(); 50 | return meta.sendCoin(account_two, amount, {from: account_one}); 51 | }).then(function() { 52 | return meta.getBalance.call(account_one); 53 | }).then(function(balance) { 54 | account_one_ending_balance = balance.toNumber(); 55 | return meta.getBalance.call(account_two); 56 | }).then(function(balance) { 57 | account_two_ending_balance = balance.toNumber(); 58 | 59 | assert.equal(account_one_ending_balance, account_one_starting_balance - amount, "Amount wasn't correctly taken from the sender"); 60 | assert.equal(account_two_ending_balance, account_two_starting_balance + amount, "Amount wasn't correctly sent to the receiver"); 61 | }); 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # web3_demo 2 | A resource repository, containing examples and templates for the web3 API and Metamask plugin 3 | 4 | ## Prerequisites 5 | You need to know how to use the command prompt and how to change your working directory and execute commands. 6 | You can take a look at [this tutorial](https://www.youtube.com/watch?v=MBBWVgE0ewk). 7 | 8 | ## Setup 9 | 10 | 1. Install node.js 11 | 2. To install `truffle` (Solidity development framework), `web3` and `http-server` (allows you to host local HTML as a website), run: 12 | 13 | You may need Admin priviledges. Try to open the command prompt as an administrator. 14 | 15 | ```bash 16 | npm install -g truffle web3@0.20.4 http-server 17 | ``` 18 | 19 | 3. Clone this GitHub repository 20 | 21 | If you have git installed, run: 22 | ``` 23 | git clone https://github.com/universe1216/web3-demo 24 | ``` 25 | 26 | Or just download the repository as a zip and extract somewhere 27 | 28 | 4. Navigate to the repository and run: 29 | ``` 30 | npm install 31 | ``` 32 | 33 | This will install the node dependencies of the example project, which are a local install of `truffle` and `web3`. 34 | 35 | ## Running a local blockchain 36 | 37 | You need to **navigate to the truffle folder** of the project and run: 38 | ``` 39 | truffle develop 40 | ``` 41 | 42 | If you get an error while doing that, try to run the same command from **git bash** - it should be installed automatically with [Git](https://git-scm.com/downloads). 43 | 44 | ## Connecting to the local Ethereum node via `Node.js` 45 | 46 | Not to confuse `Node.js` with your Ethereum node, they have nothing in common. 47 | Navigate to the project directory and run: 48 | ``` 49 | node 50 | ``` 51 | 52 | This will put you in an interactive `Node.js` session, where you can load the web3 API and connect to the Ethereum node. 53 | 54 | ## Running the MetaMask example 55 | 56 | 1. Navigate to the `metamask_example` folder in the project and run: 57 | ```node publish.js``` 58 | 59 | This will run a script that will publish a contract on your local blockchain and print out its address. 60 | 61 | 2. Edit the `script.js` file with the new contract address 62 | 63 | 3. To host the website, while inside the metamask_example folder, run: 64 | ``` 65 | http-server 66 | ``` 67 | 68 | `Ctrl + C` closes it. 69 | 70 | 4. Install MetaMask in chrome 71 | 72 | 5. Open MetaMask and click the "Import existing DEN" 73 | 74 | 6. Copy the 12 word key that was printed out when you started your local blockchain. 75 | 76 | The 12 words are used to generate the Ethereum accounts that have Ether in your local blockchain. They should be: 77 | ``` 78 | candy maple cake sugar pudding cream honey rich smooth crumble sweet treat 79 | ``` 80 | 81 | Because every truffle develop session uses the same account set. 82 | 83 | 7. After you log in to MetaMask with this key, click on the upper left corner and choose "Custom RPC" 84 | 85 | 8. Enter the URL `http://localhost:9545/` and click save. Go back and you should have successfully connected to your local node! 86 | 87 | 9. Visit `127.0.0.1:8080` and use the website! 88 | 89 | ## Developing DAPPs 90 | 91 | You can edit the website files (html and js files) directly and they will be updated when you reload the page. **If you're using chrome, reload the page with Ctrl + Shift + R instead, because chrome will cache your last version and won't update it**. 92 | -------------------------------------------------------------------------------- /metamask_example/publish.js: -------------------------------------------------------------------------------- 1 | var Web3 = require("web3"); 2 | var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:9545")); 3 | 4 | var acc = web3.eth.accounts[0]; //get the first account 5 | 6 | //Code: 7 | /* 8 | contract Ownable { 9 | address public owner; 10 | 11 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 12 | 13 | 14 | function Ownable() public { 15 | owner = msg.sender; 16 | } 17 | 18 | modifier onlyOwner() { 19 | require(msg.sender == owner); 20 | _; 21 | } 22 | 23 | function transferOwnership(address newOwner) public onlyOwner { 24 | require(newOwner != address(0)); 25 | OwnershipTransferred(owner, newOwner); 26 | owner = newOwner; 27 | } 28 | } 29 | */ 30 | 31 | //Store this contract's compiled bytecode and ABI 32 | var abi = [{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}] 33 | var bytecode = "6060604052341561000f57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102858061005e6000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638da5cb5b14610051578063f2fde38b146100a6575b600080fd5b341561005c57600080fd5b6100646100df565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156100b157600080fd5b6100dd600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610104565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561015f57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561019b57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a7230582081efbb72c8063d07f5609b8e41937697f7c0fefba7841d589f2b21c46afef4800029" 34 | 35 | //create the contract instance. We can use this instance to publish or connect to a published contract 36 | var Contract = web3.eth.contract(abi); 37 | 38 | //create a JS Object (key-value pairs), holding the data we need to publish our contract 39 | var publishData = { 40 | "from": acc, //the account from which it will be published 41 | "data": bytecode, 42 | "gas": 4000000 //gas limit. This should be the same or lower than Ethereum's gas limit 43 | } 44 | 45 | //publish the contract, passing a callback that will be called twice. Once when the transaction is sent, and once when it is mined 46 | //the first argument is the constructor argument 47 | Contract.new(publishData, function(err, contractInstance) { 48 | if(!err) { 49 | if(contractInstance.address) { //if the contract has an address aka if the transaction is mined 50 | console.log("New contract address is :", contractInstance.address); 51 | } 52 | } else { 53 | console.error(err); //something went wrong 54 | } 55 | }); 56 | --------------------------------------------------------------------------------