├── .gitattributes ├── 9781484234433.jpg ├── Contributing.md ├── LICENSE.txt ├── chapter 5 ├── bitcoin.js └── ethereum.js ├── chapter 6 └── ethereum.js ├── errata.md ├── index.js ├── package.json ├── readme.md └── readme_Author note.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /9781484234433.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/beginning-blockchain/3414f4bfd329e1d8f559d301b037977e35d1e4c3/9781484234433.jpg -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Freeware License, some rights reserved 2 | 3 | Copyright (c) 2018 Bikramaditya Singhal, Gautam Dhameja, and Priyansu Sekhar Panda 4 | 5 | Permission is hereby granted, free of charge, to anyone obtaining a copy 6 | of this software and associated documentation files (the "Software"), 7 | to work with the Software within the limits of freeware distribution and fair use. 8 | This includes the rights to use, copy, and modify the Software for personal use. 9 | Users are also allowed and encouraged to submit corrections and modifications 10 | to the Software for the benefit of other users. 11 | 12 | It is not allowed to reuse, modify, or redistribute the Software for 13 | commercial use in any way, or for a user’s educational materials such as books 14 | or blog articles without prior permission from the copyright holder. 15 | 16 | The above copyright notice and this permission notice need to be included 17 | in all copies or substantial portions of the software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | 28 | -------------------------------------------------------------------------------- /chapter 5/bitcoin.js: -------------------------------------------------------------------------------- 1 | var btc = require('bitcoinjs-lib'); 2 | var request = require('request'); 3 | 4 | // set network for the bitcoinjs library 5 | // documentation - https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L121 6 | var network = btc.networks.testnet; 7 | 8 | // set endpoint for block explorer public API 9 | var blockExplorerTestnetApiEndpoint = 'https://testnet.blockexplorer.com/api/'; 10 | 11 | // generate two bitcoin addresses using the bitcoinjs library 12 | var getKeys = function () { 13 | var aliceKeys = btc.ECPair.makeRandom({ 14 | network: network 15 | }); 16 | var bobKeys = btc.ECPair.makeRandom({ 17 | network: network 18 | }); 19 | 20 | var alicePublic = aliceKeys.getAddress(); 21 | var alicePrivate = aliceKeys.toWIF(); 22 | 23 | var bobPublic = bobKeys.getAddress(); 24 | var bobPrivate = bobKeys.toWIF(); 25 | 26 | console.log(alicePublic, alicePrivate, bobPublic, bobPrivate); 27 | }; 28 | 29 | // gets the outputs for a bitcoin adderss 30 | var getOutputs = function (address) { 31 | var url = blockExplorerTestnetApiEndpoint + 'addr/' + address + '/utxo'; 32 | return new Promise(function (resolve, reject) { 33 | request.get(url, function (err, res, body) { 34 | if (err) { 35 | reject(err); 36 | } 37 | resolve(body); 38 | }); 39 | }); 40 | }; 41 | 42 | // creates, signs and sends a bitcoin testnet transaction 43 | var createTransaction = function () { 44 | 45 | // use your own generated addresses when running this code 46 | var alice = btc.ECPair.fromWIF('cQQhHcH6C7A9VNFtGdwaSwNDRpNHDfYrPc3XnS9Puz4HHU4axM2z', network); 47 | var bob = btc.ECPair.fromWIF('cW1MB2G86LqJ9sy8cUeuxotmuaU5LyMMZffvpaFxbUw144dj1QpP', network); 48 | 49 | getOutputs(alice.getAddress()).then(function (res) { 50 | var utxo = JSON.parse(res.toString()); 51 | console.log(utxo); 52 | 53 | // make sure that the addresses you are using have enough bitcoins... 54 | // for this transaction to go through 55 | var transaction = new btc.TransactionBuilder(network); 56 | transaction.addInput(utxo[0].txid, utxo[0].vout); 57 | transaction.addOutput(alice.getAddress(), 99992000); 58 | transaction.sign(0, bob); 59 | var transactionHex = transaction.build().toHex(); 60 | 61 | var txPushUrl = blockExplorerTestnetApiEndpoint + 'tx/send'; 62 | request.post({ 63 | url: txPushUrl, 64 | json: { 65 | rawtx: transactionHex 66 | } 67 | }, function (err, res, body) { 68 | if (err) console.log(err); 69 | 70 | console.log(res); 71 | console.log(body); 72 | }); 73 | }); 74 | }; 75 | 76 | module.exports = { 77 | getKeys: getKeys, 78 | createTransaction: createTransaction 79 | }; -------------------------------------------------------------------------------- /chapter 5/ethereum.js: -------------------------------------------------------------------------------- 1 | var Web3 = require('web3'); 2 | 3 | var INFURA_API_PATH = 'https://ropsten.infura.io/'; 4 | 5 | // initilize web3 object with the infura API path as the provider 6 | var web3 = new Web3(new Web3.providers.HttpProvider(INFURA_API_PATH)); 7 | 8 | // creates two ethereum accounts (key pairs) using the web3.js library 9 | var createAccounts = function () { 10 | var aliceKeys = web3.eth.accounts.create(); 11 | console.log(aliceKeys); 12 | 13 | var bobKeys = web3.eth.accounts.create(); 14 | console.log(JSON.stringify(bobKeys)); 15 | }; 16 | 17 | // gets the balance of an ethereum account 18 | var getBalance = function () { 19 | // use your own generated account address 20 | web3.eth.getBalance('0xAff9d328E8181aE831Bc426347949EB7946A88DA').then(console.log); 21 | }; 22 | 23 | // creates, signs and sends a ethereum transaction 24 | var sendTransaction = function () { 25 | // use your own generated account address 26 | // make sure that the addresses you are using have enough ether... 27 | // for this transaction to go through 28 | var tx = { 29 | from: "0xc976080893e6783c871c09e9454fee13bc625107", 30 | gasPrice: "200", 31 | gas: "4200", 32 | to: '0x22013fff98c2909bbFCcdABb411D3715fDB341eA', 33 | value: "10000", 34 | data: "" 35 | }; 36 | 37 | // use the private key of the "from" address 38 | web3.eth.accounts.signTransaction(tx, '0x9fb71152b32cb90982f95e2b1bf2a5b6b2a53855eacf59d132a2b7f043cfddf5') 39 | .then(function (signedTx) { 40 | console.log(signedTx); 41 | web3.eth.sendSignedTransaction(signedTx.rawTransaction) 42 | .then(console.log); 43 | }); 44 | }; 45 | 46 | // gets the receipt of an ethereum transaction 47 | var getTransaction = function () { 48 | // use your own transaction hash 49 | web3.eth.getTransactionReceipt('0xd7291ed42b716cd244f3c4fd52c90ddcc75d57413177409a6ca329c7a2d5df70').then(console.log); 50 | } 51 | 52 | // gets all the events for a ethereum smart contract 53 | var getContractEvents = function () { 54 | // use the ABI and the address of your smart contract 55 | var helloworldContract = new web3.eth.Contract([{ 56 | "constant": true, 57 | "inputs": [], 58 | "name": "Hello", 59 | "outputs": [{ 60 | "name": "", 61 | "type": "string" 62 | }], 63 | "payable": false, 64 | "stateMutability": "view", 65 | "type": "function" 66 | }, { 67 | "inputs": [], 68 | "payable": false, 69 | "stateMutability": "nonpayable", 70 | "type": "constructor" 71 | }], '0xd5a2d13723A34522EF79bE0f1E7806E86a4578E9'); // this is the contract address 72 | 73 | helloworldContract.getPastEvents('allEvents').then(console.log) 74 | } 75 | 76 | // deploys a ethereum smart contract using an ethereum raw transaction 77 | var createContractUsingRawTransaction = function () { 78 | // use your own generated account address 79 | // make sure that the addresses you are using have enough ether... 80 | // for this transaction to go through 81 | // the data field has the byte code for the smart contract 82 | var tx = { 83 | from: "0xF68b93AE6120aF1e2311b30055976d62D7dBf531", 84 | gasPrice: "20000000000", 85 | gas: "4900000", 86 | data: "0x6060604052341561000f57600080fd5b6040805190810160405280600c81526020017f48656c6c6f20576f726c642100000000000000000000000000000000000000008152506000908051906020019061005a929190610060565b50610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6101bc806101146000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063bcdfe0d514610046575b600080fd5b341561005157600080fd5b6100596100d4565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561009957808201518184015260208101905061007e565b50505050905090810190601f1680156100c65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100dc61017c565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101725780601f1061014757610100808354040283529160200191610172565b820191906000526020600020905b81548152906001019060200180831161015557829003601f168201915b5050505050905090565b6020604051908101604052806000815250905600a165627a7a72305820877a5da4f7e05c4ad9b45dd10fb6c133a523541ed06db6dd31d59b35d51768a30029" 87 | }; 88 | 89 | // use the private key of the "from" address 90 | web3.eth.accounts.signTransaction(tx, '0xc6676b7262dab1a3a28a781c77110b63ab8cd5eae2a5a828ba3b1ad28e9f5a9b') 91 | .then(function (signedTx) { 92 | web3.eth.sendSignedTransaction(signedTx.rawTransaction) 93 | .then(console.log); 94 | }); 95 | } 96 | 97 | // deploys a ethereum smart contract using web3.eth.contract module 98 | var createContract = function () { 99 | // use the ABI of your smart contract 100 | var helloworldContract = new web3.eth.Contract([{ 101 | "constant": true, 102 | "inputs": [], 103 | "name": "Hello", 104 | "outputs": [{ 105 | "name": "", 106 | "type": "string" 107 | }], 108 | "payable": false, 109 | "stateMutability": "view", 110 | "type": "function" 111 | }, { 112 | "inputs": [], 113 | "payable": false, 114 | "stateMutability": "nonpayable", 115 | "type": "constructor" 116 | }]); 117 | 118 | // the data field has the byte code for the smart contract 119 | helloworldContract 120 | .deploy({ 121 | data: '0x6060604052341561000f57600080fd5b6040805190810160405280600c81526020017f48656c6c6f20576f726c642100000000000000000000000000000000000000008152506000908051906020019061005a929190610060565b50610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6101bc806101146000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063bcdfe0d514610046575b600080fd5b341561005157600080fd5b6100596100d4565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561009957808201518184015260208101905061007e565b50505050905090810190601f1680156100c65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100dc61017c565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101725780601f1061014757610100808354040283529160200191610172565b820191906000526020600020905b81548152906001019060200180831161015557829003601f168201915b5050505050905090565b6020604051908101604052806000815250905600a165627a7a72305820877a5da4f7e05c4ad9b45dd10fb6c133a523541ed06db6dd31d59b35d51768a30029' 122 | }) 123 | .send({ 124 | from: '0xF68b93AE6120aF1e2311b30055976d62D7dBf531', 125 | gas: 4700000, 126 | gasPrice: '20000000000' 127 | }, 128 | function (error, transactionHash) { 129 | console.log(error); 130 | console.log(transactionHash); 131 | }) 132 | .then(function (contract) { 133 | console.log(contract); 134 | }); 135 | }; 136 | 137 | // calls/executes a ethereum smart contract function 138 | var callContract = function () { 139 | // use the ABI and the address of your smart contract 140 | var helloworldContract = new web3.eth.Contract([{ 141 | "constant": true, 142 | "inputs": [], 143 | "name": "Hello", 144 | "outputs": [{ 145 | "name": "", 146 | "type": "string" 147 | }], 148 | "payable": false, 149 | "stateMutability": "view", 150 | "type": "function" 151 | }, { 152 | "inputs": [], 153 | "payable": false, 154 | "stateMutability": "nonpayable", 155 | "type": "constructor" 156 | }], '0xd5a2d13723A34522EF79bE0f1E7806E86a4578E9'); // this is the contract address 157 | 158 | helloworldContract.methods.Hello().send({ 159 | from: '0xF68b93AE6120aF1e2311b30055976d62D7dBf531' 160 | }).then(console.log); 161 | }; 162 | 163 | module.exports = { 164 | createAccounts: createAccounts, 165 | getBalance: getBalance, 166 | sendTransaction: sendTransaction, 167 | createContract: createContract, 168 | getTransaction: getTransaction, 169 | callContract: callContract, 170 | getContractEvents: getContractEvents, 171 | createContractUsingRawTransaction: createContractUsingRawTransaction 172 | }; -------------------------------------------------------------------------------- /chapter 6/ethereum.js: -------------------------------------------------------------------------------- 1 | var Web3 = require('web3'); 2 | 3 | // RPC API path of your local geth node 4 | // run the local geth node as described in the chapter 6 5 | var RPC_PATH = "http://127.0.0.1:8545" 6 | 7 | // initilize web3 object with the local node path as the provider 8 | var web3 = new Web3(new Web3.providers.HttpProvider(RPC_PATH)); 9 | 10 | // creates account on the local ethereum geth node using web3.personal module 11 | var createAccount = function () { 12 | // replace "abcd" with the password of your choice 13 | web3.eth.personal.newAccount('abcd').then(console.log); 14 | }; 15 | 16 | // unlocks an account on the local ethereum geth node using web3.personal module 17 | var unlockAccount = function () { 18 | // use your own account address and password 19 | web3.eth.personal.unlockAccount('0xbaf735f889d603f0ec6b1030c91d9033e60525c3', 'abcd').then(console.log); 20 | } 21 | 22 | // deploys the smart contract for polling dApp as described in chapter 6 23 | // uses the web3.eth.Contract module to deploy the contract 24 | var deployContract = function () { 25 | var pollingContract = new web3.eth.Contract([{ 26 | "constant": true, 27 | "inputs": [{ 28 | "name": "", 29 | "type": "address" 30 | }], 31 | "name": "votes", 32 | "outputs": [{ 33 | "name": "", 34 | "type": "uint256" 35 | }], 36 | "payable": false, 37 | "stateMutability": "view", 38 | "type": "function" 39 | }, 40 | { 41 | "constant": true, 42 | "inputs": [], 43 | "name": "getPoll", 44 | "outputs": [{ 45 | "name": "", 46 | "type": "string" 47 | }], 48 | "payable": false, 49 | "stateMutability": "view", 50 | "type": "function" 51 | }, 52 | { 53 | "anonymous": false, 54 | "inputs": [{ 55 | "indexed": false, 56 | "name": "_voter", 57 | "type": "address" 58 | }, 59 | { 60 | "indexed": false, 61 | "name": "_value", 62 | "type": "uint256" 63 | } 64 | ], 65 | "name": "Voted", 66 | "type": "event" 67 | }, 68 | { 69 | "constant": false, 70 | "inputs": [{ 71 | "name": "selection", 72 | "type": "uint256" 73 | }], 74 | "name": "vote", 75 | "outputs": [], 76 | "payable": false, 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | } 80 | ]); 81 | pollingContract 82 | .deploy({ 83 | data: '0x6060604052608060405190810160405280605081526020017f53686f756c6420636f66666565206265206d6164652074617820667265653f2081526020017f53656e64203120666f7220796573204f52203220666f72206e6f20696e20746881526020017f6520766f74652066756e6374696f6e2e000000000000000000000000000000008152506001908051906020019061009c9291906100ad565b5034156100a857600080fd5b610152565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100ee57805160ff191683800117855561011c565b8280016001018555821561011c579182015b8281111561011b578251825591602001919060010190610100565b5b509050610129919061012d565b5090565b61014f91905b8082111561014b576000816000905550600101610133565b5090565b90565b610373806101616000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630121b93f1461005c57806303c322781461007f578063d8bff5a51461010d575b600080fd5b341561006757600080fd5b61007d600480803590602001909190505061015a565b005b341561008a57600080fd5b610092610273565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100d25780820151818401526020810190506100b7565b50505050905090810190601f1680156100ff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561011857600080fd5b610144600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061031b565b6040518082815260200191505060405180910390f35b7f4d99b957a2bc29a30ebd96a7be8e68fe50a3c701db28a91436490b7d53870ca43382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a160008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414151561021257600080fd5b6000811180156102225750600381105b151561022d57600080fd5b806000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050565b61027b610333565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103115780601f106102e657610100808354040283529160200191610311565b820191906000526020600020905b8154815290600101906020018083116102f457829003601f168201915b5050505050905090565b60006020528060005260406000206000915090505481565b6020604051908101604052806000815250905600a165627a7a72305820ec7d3e1dae8412ec85045a8eafc248e37ae506802cc008ead300df1ac81aab490029' 84 | }) 85 | .send({ 86 | from: '0xbaf735f889d603f0ec6b1030c91d9033e60525c3', 87 | gas: 4700000, 88 | gasPrice: '20000000000000' 89 | }, 90 | function (error, transactionHash) { 91 | console.log(error); 92 | console.log(transactionHash); 93 | }) 94 | .then(function (contract) { 95 | console.log(contract); 96 | }); 97 | }; 98 | 99 | // calls the getPoll smart contract function for polling contract as described in chapter 6 100 | // uses the web3.eth.Contract module 101 | var callContractGetPoll = function () { 102 | var pollingContract = new web3.eth.Contract([{ 103 | "constant": true, 104 | "inputs": [{ 105 | "name": "", 106 | "type": "address" 107 | }], 108 | "name": "votes", 109 | "outputs": [{ 110 | "name": "", 111 | "type": "uint256" 112 | }], 113 | "payable": false, 114 | "stateMutability": "view", 115 | "type": "function" 116 | }, 117 | { 118 | "constant": true, 119 | "inputs": [], 120 | "name": "getPoll", 121 | "outputs": [{ 122 | "name": "", 123 | "type": "string" 124 | }], 125 | "payable": false, 126 | "stateMutability": "view", 127 | "type": "function" 128 | }, 129 | { 130 | "anonymous": false, 131 | "inputs": [{ 132 | "indexed": false, 133 | "name": "_voter", 134 | "type": "address" 135 | }, 136 | { 137 | "indexed": false, 138 | "name": "_value", 139 | "type": "uint256" 140 | } 141 | ], 142 | "name": "Voted", 143 | "type": "event" 144 | }, 145 | { 146 | "constant": false, 147 | "inputs": [{ 148 | "name": "selection", 149 | "type": "uint256" 150 | }], 151 | "name": "vote", 152 | "outputs": [], 153 | "payable": false, 154 | "stateMutability": "nonpayable", 155 | "type": "function" 156 | } 157 | ], '0x59E7161646C3436DFdF5eBE617B4A172974B481e'); 158 | 159 | pollingContract.methods.getPoll().call().then(console.log); 160 | }; 161 | 162 | // executes the vote smart contract function for polling contract as described in chapter 6 163 | // uses the web3.eth.Contract module 164 | var executeContractVote = function (voteValue = 1) { 165 | var pollingContract = new web3.eth.Contract([{ 166 | "constant": true, 167 | "inputs": [{ 168 | "name": "", 169 | "type": "address" 170 | }], 171 | "name": "votes", 172 | "outputs": [{ 173 | "name": "", 174 | "type": "uint256" 175 | }], 176 | "payable": false, 177 | "stateMutability": "view", 178 | "type": "function" 179 | }, 180 | { 181 | "constant": true, 182 | "inputs": [], 183 | "name": "getPoll", 184 | "outputs": [{ 185 | "name": "", 186 | "type": "string" 187 | }], 188 | "payable": false, 189 | "stateMutability": "view", 190 | "type": "function" 191 | }, 192 | { 193 | "anonymous": false, 194 | "inputs": [{ 195 | "indexed": false, 196 | "name": "_voter", 197 | "type": "address" 198 | }, 199 | { 200 | "indexed": false, 201 | "name": "_value", 202 | "type": "uint256" 203 | } 204 | ], 205 | "name": "Voted", 206 | "type": "event" 207 | }, 208 | { 209 | "constant": false, 210 | "inputs": [{ 211 | "name": "selection", 212 | "type": "uint256" 213 | }], 214 | "name": "vote", 215 | "outputs": [], 216 | "payable": false, 217 | "stateMutability": "nonpayable", 218 | "type": "function" 219 | } 220 | ], '0x59E7161646C3436DFdF5eBE617B4A172974B481e'); 221 | 222 | pollingContract.methods.vote(voteValue).send({ 223 | from: '0xbaf735f889d603f0ec6b1030c91d9033e60525c3' 224 | }).then(function (result) { 225 | console.log(result); 226 | }); 227 | }; 228 | 229 | // gets all the events for the polling smart contract as described in chapter 6 230 | var getContractEvents = function () { 231 | var pollingContract = new web3.eth.Contract([{ 232 | "constant": true, 233 | "inputs": [{ 234 | "name": "", 235 | "type": "address" 236 | }], 237 | "name": "votes", 238 | "outputs": [{ 239 | "name": "", 240 | "type": "uint256" 241 | }], 242 | "payable": false, 243 | "stateMutability": "view", 244 | "type": "function" 245 | }, 246 | { 247 | "constant": true, 248 | "inputs": [], 249 | "name": "getPoll", 250 | "outputs": [{ 251 | "name": "", 252 | "type": "string" 253 | }], 254 | "payable": false, 255 | "stateMutability": "view", 256 | "type": "function" 257 | }, 258 | { 259 | "anonymous": false, 260 | "inputs": [{ 261 | "indexed": false, 262 | "name": "_voter", 263 | "type": "address" 264 | }, 265 | { 266 | "indexed": false, 267 | "name": "_value", 268 | "type": "uint256" 269 | } 270 | ], 271 | "name": "Voted", 272 | "type": "event" 273 | }, 274 | { 275 | "constant": false, 276 | "inputs": [{ 277 | "name": "selection", 278 | "type": "uint256" 279 | }], 280 | "name": "vote", 281 | "outputs": [], 282 | "payable": false, 283 | "stateMutability": "nonpayable", 284 | "type": "function" 285 | } 286 | ], '0x59E7161646C3436DFdF5eBE617B4A172974B481e'); 287 | 288 | pollingContract.getPastEvents('allEvents').then(console.log); 289 | }; 290 | 291 | module.exports = { 292 | createAccount: createAccount, 293 | deployContract: deployContract, 294 | unlockAccount: unlockAccount, 295 | callContractGetPoll: callContractGetPoll, 296 | executeContractVote: executeContractVote, 297 | getContractEvents: getContractEvents 298 | }; -------------------------------------------------------------------------------- /errata.md: -------------------------------------------------------------------------------- 1 | # Errata for *Book Title* 2 | 3 | On **page xx** [Summary of error]: 4 | 5 | Details of error here. Highlight key pieces in **bold**. 6 | 7 | *** 8 | 9 | On **page xx** [Summary of error]: 10 | 11 | Details of error here. Highlight key pieces in **bold**. 12 | 13 | *** -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var eth = require('./chapter 6/ethereum'); 2 | 3 | (function(){ 4 | eth.createAccount(); 5 | })(); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beginning-blockchain", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bitcoinjs-lib": "^3.3.2", 13 | "request": "^2.83.0", 14 | "web3": "^1.0.0-beta.28" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*Beginning Blockchain*](https://www.apress.com/9781484234433) by Bikramaditya Singhal, Gautam Dhameja, and Priyansu Sekhar Panda (Apress, 2018). 4 | 5 | [comment]: #cover 6 | ![Cover image](9781484234433.jpg) 7 | 8 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 9 | 10 | ## Releases 11 | 12 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 13 | 14 | ## Contributions 15 | 16 | See the file Contributing.md for more information on how you can contribute to this repository. -------------------------------------------------------------------------------- /readme_Author note.md: -------------------------------------------------------------------------------- 1 | # Beginning Blockchain - Source Code 2 | 3 | This file describes how to use this source code package for the Beginning Blockchain book. 4 | 5 | ## Contents 6 | 7 | 1. This source code package contains source code for chapters 5 and 6 of the book. 8 | 2. All code is JavaScript with an exception of HTML/CSS for calling smart contract code in chapter 6 9 | 3. The JavaScript files are wrapped inside a **nodejs** application which is represented by the `package.json` file in the root of this directory. 10 | 4. All required node module (packages) are listed in the `dependencies` section of the `package.json` file 11 | 12 | ## Directory structure 13 | 14 | All concepts covered in chapters 5 and 6 which have source code involved, have the corresponding source code in this package. 15 | This package's root directory is structure with it's contents as below, 16 | * `package.json` (as described above) 17 | * `index.js` as an entry point for the nodejs application 18 | * directory for chapter 5 code 19 | * directory for chapter 6 code 20 | 21 | The **chapter 5** directory has two JavaScript files, `bitcoin.js` and `ethereum.js` each for Bitcoin and Ethereum code. 22 | The **chapter 6** directory has just one JavaScript file, `ethereum.js`, as all the code in chapter 6 is for Ethereum dApp development. 23 | The JavaScript files in the directories have code divided into functions for each concept. 24 | All functions have comments describing the code written in them. 25 | 26 | ## How to execute 27 | 28 | A basic understanding of JavaScript and nodejs is expected from the reader. 29 | 30 | For every function to execute, 31 | * include the corresponding JavaScript file using the `require` statement in the `index.js` 32 | * call the function inside the default function of `index.js`. 33 | 34 | > In the following code snippet, we are calling the `getKeys` function inside the `bitcoin.js` of chapter 5 directory. 35 | 36 | ``` 37 | var btc = require('./chapter 5/bitcoin'); 38 | 39 | (function(){ 40 | btc.getKeys(); 41 | })(); 42 | ``` 43 | 44 | > Similarly, in the following code snippet, we are calling the `createAccounts` function inside the `ethereum.js` of chapter 6 directory. 45 | 46 | ``` 47 | var eth = require('./chapter 6/ethereum'); 48 | 49 | (function(){ 50 | eth.createAccounts(); 51 | })(); 52 | ``` --------------------------------------------------------------------------------