├── .babelrc ├── .eslintrc ├── LICENSE ├── README.md ├── build └── contracts │ ├── BasicToken.json │ ├── ERC20.json │ ├── ERC20Basic.json │ ├── Migrations.json │ ├── MintableToken.json │ ├── Multiplexer.json │ ├── Ownable.json │ ├── SafeMath.json │ ├── StandardToken.json │ └── TestMintableToken.json ├── contracts ├── ERC20.sol ├── Multiplexer.sol └── TestMintableToken.sol ├── migrations └── 1_deploy.js ├── package-lock.json ├── package.json ├── scripts └── dgd-reward.js ├── test ├── Multiplexer.js └── RunScriptWithWorkingWeb3.js └── truffle.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ "env", "stage-0" ] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "env" : { "mocha": true }, 4 | "globals" : { 5 | "assert": true, 6 | "artifacts": true, 7 | "contract": true, 8 | "web3": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, DigixGlobal Private Limited 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multiplexer 2 | 3 | See `/build/contracts/Multiplexer.json` for deployment details. 4 | 5 | ## Usage 6 | 7 | You must pass an array of addresses and an array of values to send to those addresses (by index) 8 | 9 | ### Send Ether 10 | 11 | ``` 12 | function sendEth(address[] _to, uint256[] _value) payable returns (bool _success) 13 | ``` 14 | 15 | ### Send ERC20 Tokens 16 | 17 | First you must `approve` the multiplexer contract address with enough tokens to process your request 18 | 19 | ``` 20 | function sendErc20(address _tokenAddress, address[] _to, uint256[] _value) returns (bool _success) 21 | ``` 22 | -------------------------------------------------------------------------------- /build/contracts/BasicToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "BasicToken", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "totalSupply", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "uint256" 12 | } 13 | ], 14 | "payable": false, 15 | "stateMutability": "view", 16 | "type": "function" 17 | }, 18 | { 19 | "constant": true, 20 | "inputs": [ 21 | { 22 | "name": "_owner", 23 | "type": "address" 24 | } 25 | ], 26 | "name": "balanceOf", 27 | "outputs": [ 28 | { 29 | "name": "balance", 30 | "type": "uint256" 31 | } 32 | ], 33 | "payable": false, 34 | "stateMutability": "view", 35 | "type": "function" 36 | }, 37 | { 38 | "constant": false, 39 | "inputs": [ 40 | { 41 | "name": "_to", 42 | "type": "address" 43 | }, 44 | { 45 | "name": "_value", 46 | "type": "uint256" 47 | } 48 | ], 49 | "name": "transfer", 50 | "outputs": [ 51 | { 52 | "name": "", 53 | "type": "bool" 54 | } 55 | ], 56 | "payable": false, 57 | "stateMutability": "nonpayable", 58 | "type": "function" 59 | }, 60 | { 61 | "anonymous": false, 62 | "inputs": [ 63 | { 64 | "indexed": true, 65 | "name": "from", 66 | "type": "address" 67 | }, 68 | { 69 | "indexed": true, 70 | "name": "to", 71 | "type": "address" 72 | }, 73 | { 74 | "indexed": false, 75 | "name": "value", 76 | "type": "uint256" 77 | } 78 | ], 79 | "name": "Transfer", 80 | "type": "event" 81 | } 82 | ], 83 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b6102218061001f6000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318160ddd811461005357806370a0823114610078578063a9059cbb146100a9575b600080fd5b341561005e57600080fd5b6100666100df565b60405190815260200160405180910390f35b341561008357600080fd5b610066600160a060020a03600435166100e5565b60405190815260200160405180910390f35b34156100b457600080fd5b6100cb600160a060020a0360043516602435610104565b604051901515815260200160405180910390f35b60005481565b600160a060020a0381166000908152600160205260409020545b919050565b600160a060020a03331660009081526001602052604081205461012d908363ffffffff6101c416565b600160a060020a033381166000908152600160205260408082209390935590851681522054610162908363ffffffff6101db16565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060015b92915050565b6000828211156101d057fe5b508082035b92915050565b6000828201838110156101ea57fe5b8091505b50929150505600a165627a7a723058203e7cc5648a994c3ba8e34f4601b20485ae08b45d1f349e205d569e527633fc620029", 84 | "networks": {}, 85 | "schema_version": "0.0.5", 86 | "updated_at": 1505289116288 87 | } -------------------------------------------------------------------------------- /build/contracts/ERC20.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "ERC20", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [ 7 | { 8 | "name": "from", 9 | "type": "address" 10 | }, 11 | { 12 | "name": "to", 13 | "type": "address" 14 | }, 15 | { 16 | "name": "value", 17 | "type": "uint256" 18 | } 19 | ], 20 | "name": "transferFrom", 21 | "outputs": [ 22 | { 23 | "name": "ok", 24 | "type": "bool" 25 | } 26 | ], 27 | "payable": false, 28 | "stateMutability": "nonpayable", 29 | "type": "function" 30 | } 31 | ], 32 | "unlinked_binary": "0x", 33 | "networks": {}, 34 | "schema_version": "0.0.5", 35 | "updated_at": 1505298584639 36 | } -------------------------------------------------------------------------------- /build/contracts/ERC20Basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "ERC20Basic", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "totalSupply", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "uint256" 12 | } 13 | ], 14 | "payable": false, 15 | "stateMutability": "view", 16 | "type": "function" 17 | }, 18 | { 19 | "constant": true, 20 | "inputs": [ 21 | { 22 | "name": "who", 23 | "type": "address" 24 | } 25 | ], 26 | "name": "balanceOf", 27 | "outputs": [ 28 | { 29 | "name": "", 30 | "type": "uint256" 31 | } 32 | ], 33 | "payable": false, 34 | "stateMutability": "view", 35 | "type": "function" 36 | }, 37 | { 38 | "constant": false, 39 | "inputs": [ 40 | { 41 | "name": "to", 42 | "type": "address" 43 | }, 44 | { 45 | "name": "value", 46 | "type": "uint256" 47 | } 48 | ], 49 | "name": "transfer", 50 | "outputs": [ 51 | { 52 | "name": "", 53 | "type": "bool" 54 | } 55 | ], 56 | "payable": false, 57 | "stateMutability": "nonpayable", 58 | "type": "function" 59 | }, 60 | { 61 | "anonymous": false, 62 | "inputs": [ 63 | { 64 | "indexed": true, 65 | "name": "from", 66 | "type": "address" 67 | }, 68 | { 69 | "indexed": true, 70 | "name": "to", 71 | "type": "address" 72 | }, 73 | { 74 | "indexed": false, 75 | "name": "value", 76 | "type": "uint256" 77 | } 78 | ], 79 | "name": "Transfer", 80 | "type": "event" 81 | } 82 | ], 83 | "unlinked_binary": "0x", 84 | "networks": {}, 85 | "schema_version": "0.0.5", 86 | "updated_at": 1505289116288 87 | } -------------------------------------------------------------------------------- /build/contracts/Migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Migrations", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [ 7 | { 8 | "name": "new_address", 9 | "type": "address" 10 | } 11 | ], 12 | "name": "upgrade", 13 | "outputs": [], 14 | "payable": false, 15 | "stateMutability": "nonpayable", 16 | "type": "function" 17 | }, 18 | { 19 | "constant": true, 20 | "inputs": [], 21 | "name": "last_completed_migration", 22 | "outputs": [ 23 | { 24 | "name": "", 25 | "type": "uint256" 26 | } 27 | ], 28 | "payable": false, 29 | "stateMutability": "view", 30 | "type": "function" 31 | }, 32 | { 33 | "constant": true, 34 | "inputs": [], 35 | "name": "owner", 36 | "outputs": [ 37 | { 38 | "name": "", 39 | "type": "address" 40 | } 41 | ], 42 | "payable": false, 43 | "stateMutability": "view", 44 | "type": "function" 45 | }, 46 | { 47 | "constant": false, 48 | "inputs": [ 49 | { 50 | "name": "completed", 51 | "type": "uint256" 52 | } 53 | ], 54 | "name": "setCompleted", 55 | "outputs": [], 56 | "payable": false, 57 | "stateMutability": "nonpayable", 58 | "type": "function" 59 | }, 60 | { 61 | "inputs": [], 62 | "payable": false, 63 | "stateMutability": "nonpayable", 64 | "type": "constructor" 65 | } 66 | ], 67 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b6101e58061003c6000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630900f010811461005e578063445df0ac1461007f5780638da5cb5b146100a4578063fdacd576146100d3575b600080fd5b341561006957600080fd5b61007d600160a060020a03600435166100eb565b005b341561008a57600080fd5b610092610182565b60405190815260200160405180910390f35b34156100af57600080fd5b6100b7610188565b604051600160a060020a03909116815260200160405180910390f35b34156100de57600080fd5b61007d600435610197565b005b6000805433600160a060020a039081169116141561017c5781905080600160a060020a031663fdacd5766001546040517c010000000000000000000000000000000000000000000000000000000063ffffffff84160281526004810191909152602401600060405180830381600087803b151561016757600080fd5b6102c65a03f1151561017857600080fd5b5050505b5b5b5050565b60015481565b600054600160a060020a031681565b60005433600160a060020a03908116911614156101b45760018190555b5b5b505600a165627a7a723058200f5c21800b303b6fe7516e278d47e6d735daf6e7469993f768facc69d4dc7dec0029", 68 | "networks": { 69 | "1": { 70 | "links": {}, 71 | "events": {}, 72 | "updated_at": 1505297153002 73 | }, 74 | "42": { 75 | "links": {}, 76 | "events": {}, 77 | "updated_at": 1505292076768 78 | } 79 | }, 80 | "schema_version": "0.0.5", 81 | "updated_at": 1505297228085 82 | } -------------------------------------------------------------------------------- /build/contracts/MintableToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "MintableToken", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "mintingFinished", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "bool" 12 | } 13 | ], 14 | "payable": false, 15 | "stateMutability": "view", 16 | "type": "function" 17 | }, 18 | { 19 | "constant": false, 20 | "inputs": [ 21 | { 22 | "name": "_spender", 23 | "type": "address" 24 | }, 25 | { 26 | "name": "_value", 27 | "type": "uint256" 28 | } 29 | ], 30 | "name": "approve", 31 | "outputs": [ 32 | { 33 | "name": "", 34 | "type": "bool" 35 | } 36 | ], 37 | "payable": false, 38 | "stateMutability": "nonpayable", 39 | "type": "function" 40 | }, 41 | { 42 | "constant": true, 43 | "inputs": [], 44 | "name": "totalSupply", 45 | "outputs": [ 46 | { 47 | "name": "", 48 | "type": "uint256" 49 | } 50 | ], 51 | "payable": false, 52 | "stateMutability": "view", 53 | "type": "function" 54 | }, 55 | { 56 | "constant": false, 57 | "inputs": [ 58 | { 59 | "name": "_from", 60 | "type": "address" 61 | }, 62 | { 63 | "name": "_to", 64 | "type": "address" 65 | }, 66 | { 67 | "name": "_value", 68 | "type": "uint256" 69 | } 70 | ], 71 | "name": "transferFrom", 72 | "outputs": [ 73 | { 74 | "name": "", 75 | "type": "bool" 76 | } 77 | ], 78 | "payable": false, 79 | "stateMutability": "nonpayable", 80 | "type": "function" 81 | }, 82 | { 83 | "constant": false, 84 | "inputs": [ 85 | { 86 | "name": "_to", 87 | "type": "address" 88 | }, 89 | { 90 | "name": "_amount", 91 | "type": "uint256" 92 | } 93 | ], 94 | "name": "mint", 95 | "outputs": [ 96 | { 97 | "name": "", 98 | "type": "bool" 99 | } 100 | ], 101 | "payable": false, 102 | "stateMutability": "nonpayable", 103 | "type": "function" 104 | }, 105 | { 106 | "constant": true, 107 | "inputs": [ 108 | { 109 | "name": "_owner", 110 | "type": "address" 111 | } 112 | ], 113 | "name": "balanceOf", 114 | "outputs": [ 115 | { 116 | "name": "balance", 117 | "type": "uint256" 118 | } 119 | ], 120 | "payable": false, 121 | "stateMutability": "view", 122 | "type": "function" 123 | }, 124 | { 125 | "constant": false, 126 | "inputs": [], 127 | "name": "finishMinting", 128 | "outputs": [ 129 | { 130 | "name": "", 131 | "type": "bool" 132 | } 133 | ], 134 | "payable": false, 135 | "stateMutability": "nonpayable", 136 | "type": "function" 137 | }, 138 | { 139 | "constant": true, 140 | "inputs": [], 141 | "name": "owner", 142 | "outputs": [ 143 | { 144 | "name": "", 145 | "type": "address" 146 | } 147 | ], 148 | "payable": false, 149 | "stateMutability": "view", 150 | "type": "function" 151 | }, 152 | { 153 | "constant": false, 154 | "inputs": [ 155 | { 156 | "name": "_to", 157 | "type": "address" 158 | }, 159 | { 160 | "name": "_value", 161 | "type": "uint256" 162 | } 163 | ], 164 | "name": "transfer", 165 | "outputs": [ 166 | { 167 | "name": "", 168 | "type": "bool" 169 | } 170 | ], 171 | "payable": false, 172 | "stateMutability": "nonpayable", 173 | "type": "function" 174 | }, 175 | { 176 | "constant": true, 177 | "inputs": [ 178 | { 179 | "name": "_owner", 180 | "type": "address" 181 | }, 182 | { 183 | "name": "_spender", 184 | "type": "address" 185 | } 186 | ], 187 | "name": "allowance", 188 | "outputs": [ 189 | { 190 | "name": "remaining", 191 | "type": "uint256" 192 | } 193 | ], 194 | "payable": false, 195 | "stateMutability": "view", 196 | "type": "function" 197 | }, 198 | { 199 | "constant": false, 200 | "inputs": [ 201 | { 202 | "name": "newOwner", 203 | "type": "address" 204 | } 205 | ], 206 | "name": "transferOwnership", 207 | "outputs": [], 208 | "payable": false, 209 | "stateMutability": "nonpayable", 210 | "type": "function" 211 | }, 212 | { 213 | "anonymous": false, 214 | "inputs": [ 215 | { 216 | "indexed": true, 217 | "name": "to", 218 | "type": "address" 219 | }, 220 | { 221 | "indexed": false, 222 | "name": "amount", 223 | "type": "uint256" 224 | } 225 | ], 226 | "name": "Mint", 227 | "type": "event" 228 | }, 229 | { 230 | "anonymous": false, 231 | "inputs": [], 232 | "name": "MintFinished", 233 | "type": "event" 234 | }, 235 | { 236 | "anonymous": false, 237 | "inputs": [ 238 | { 239 | "indexed": true, 240 | "name": "owner", 241 | "type": "address" 242 | }, 243 | { 244 | "indexed": true, 245 | "name": "spender", 246 | "type": "address" 247 | }, 248 | { 249 | "indexed": false, 250 | "name": "value", 251 | "type": "uint256" 252 | } 253 | ], 254 | "name": "Approval", 255 | "type": "event" 256 | }, 257 | { 258 | "anonymous": false, 259 | "inputs": [ 260 | { 261 | "indexed": true, 262 | "name": "from", 263 | "type": "address" 264 | }, 265 | { 266 | "indexed": true, 267 | "name": "to", 268 | "type": "address" 269 | }, 270 | { 271 | "indexed": false, 272 | "name": "value", 273 | "type": "uint256" 274 | } 275 | ], 276 | "name": "Transfer", 277 | "type": "event" 278 | } 279 | ], 280 | "unlinked_binary": "0x60606040526003805460a060020a60ff02191690555b60038054600160a060020a03191633600160a060020a03161790555b5b6107d6806100416000396000f300606060405236156100ac5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166305d2035b81146100b1578063095ea7b3146100d857806318160ddd1461010e57806323b872dd1461013357806340c10f191461016f57806370a08231146101a55780637d64bcb4146101d65780638da5cb5b146101fd578063a9059cbb1461022c578063dd62ed3e14610262578063f2fde38b14610299575b600080fd5b34156100bc57600080fd5b6100c46102ba565b604051901515815260200160405180910390f35b34156100e357600080fd5b6100c4600160a060020a03600435166024356102db565b604051901515815260200160405180910390f35b341561011957600080fd5b610121610382565b60405190815260200160405180910390f35b341561013e57600080fd5b6100c4600160a060020a0360043581169060243516604435610388565b604051901515815260200160405180910390f35b341561017a57600080fd5b6100c4600160a060020a036004351660243561049d565b604051901515815260200160405180910390f35b34156101b057600080fd5b610121600160a060020a036004351661057f565b60405190815260200160405180910390f35b34156101e157600080fd5b6100c461059e565b604051901515815260200160405180910390f35b341561020857600080fd5b610210610625565b604051600160a060020a03909116815260200160405180910390f35b341561023757600080fd5b6100c4600160a060020a0360043516602435610634565b604051901515815260200160405180910390f35b341561026d57600080fd5b610121600160a060020a03600435811690602435166106f4565b60405190815260200160405180910390f35b34156102a457600080fd5b6102b8600160a060020a0360043516610721565b005b60035474010000000000000000000000000000000000000000900460ff1681565b600081158061030d5750600160a060020a03338116600090815260026020908152604080832093871683529290522054155b151561031857600080fd5b600160a060020a03338116600081815260026020908152604080832094881680845294909152908190208590557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b60005481565b600160a060020a0380841660009081526002602090815260408083203385168452825280832054938616835260019091528120549091906103cf908463ffffffff61077916565b600160a060020a038086166000908152600160205260408082209390935590871681522054610404908463ffffffff61079316565b600160a060020a03861660009081526001602052604090205561042d818463ffffffff61079316565b600160a060020a03808716600081815260026020908152604080832033861684529091529081902093909355908616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9086905190815260200160405180910390a3600191505b509392505050565b60035460009033600160a060020a039081169116146104bb57600080fd5b60035474010000000000000000000000000000000000000000900460ff16156104e357600080fd5b6000546104f6908363ffffffff61077916565b6000908155600160a060020a038416815260016020526040902054610521908363ffffffff61077916565b600160a060020a0384166000818152600160205260409081902092909255907f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968859084905190815260200160405180910390a25060015b5b5b92915050565b600160a060020a0381166000908152600160205260409020545b919050565b60035460009033600160a060020a039081169116146105bc57600080fd5b6003805474ff00000000000000000000000000000000000000001916740100000000000000000000000000000000000000001790557fae5184fba832cb2b1f702aca6117b8d265eaf03ad33eb133f19dde0f5920fa0860405160405180910390a15060015b5b90565b600354600160a060020a031681565b600160a060020a03331660009081526001602052604081205461065d908363ffffffff61079316565b600160a060020a033381166000908152600160205260408082209390935590851681522054610692908363ffffffff61077916565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060015b92915050565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b60035433600160a060020a0390811691161461073c57600080fd5b600160a060020a03811615610774576003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b50565b60008282018381101561078857fe5b8091505b5092915050565b60008282111561079f57fe5b508082035b929150505600a165627a7a723058202f787e2b85cf060b60b5e2342665fe0b7b76eb4f9b85e90884172f787d52c7e10029", 281 | "networks": {}, 282 | "schema_version": "0.0.5", 283 | "updated_at": 1505289116288 284 | } -------------------------------------------------------------------------------- /build/contracts/Multiplexer.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Multiplexer", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [ 7 | { 8 | "name": "_to", 9 | "type": "address[]" 10 | }, 11 | { 12 | "name": "_value", 13 | "type": "uint256[]" 14 | } 15 | ], 16 | "name": "sendEth", 17 | "outputs": [ 18 | { 19 | "name": "_success", 20 | "type": "bool" 21 | } 22 | ], 23 | "payable": true, 24 | "stateMutability": "payable", 25 | "type": "function" 26 | }, 27 | { 28 | "constant": false, 29 | "inputs": [ 30 | { 31 | "name": "_tokenAddress", 32 | "type": "address" 33 | }, 34 | { 35 | "name": "_to", 36 | "type": "address[]" 37 | }, 38 | { 39 | "name": "_value", 40 | "type": "uint256[]" 41 | } 42 | ], 43 | "name": "sendErc20", 44 | "outputs": [ 45 | { 46 | "name": "_success", 47 | "type": "bool" 48 | } 49 | ], 50 | "payable": false, 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | } 54 | ], 55 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b6104288061001f6000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166325245b268114610048578063aee25613146100e0575b600080fd5b6100cc60046024813581810190830135806020818102016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284375094965061019e95505050505050565b604051901515815260200160405180910390f35b34156100eb57600080fd5b6100cc6004803573ffffffffffffffffffffffffffffffffffffffff16906044602480359081019083013580602080820201604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437509496506102c395505050505050565b604051901515815260200160405180910390f35b600080600080600085518751146101b157fe5b60ff875111156101bd57fe5b34935060009250600091505b86518260ff16101561026b57858260ff16815181106101e457fe5b9060200190602002015183019250868260ff168151811061020157fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff166108fc878460ff168151811061023357fe5b906020019060200201519081150290604051600060405180830381858888f19350505050151561025f57fe5b5b6001909101906101c9565b5081830360008111156102b35773ffffffffffffffffffffffffffffffffffffffff331681156108fc0282604051600060405180830381858888f1935050505015156102b357fe5b5b600194505b5050505092915050565b600080600083518551146102d357fe5b60ff855111156102df57fe5b5084905060005b84518160ff1610156103ee578173ffffffffffffffffffffffffffffffffffffffff166323b872dd33878460ff168151811061031e57fe5b90602001906020020151878560ff168151811061033757fe5b906020019060200201516000604051602001526040517c010000000000000000000000000000000000000000000000000000000063ffffffff861602815273ffffffffffffffffffffffffffffffffffffffff93841660048201529190921660248201526044810191909152606401602060405180830381600087803b15156103bf57600080fd5b6102c65a03f115156103d057600080fd5b5050506040518051151560011490506103e557fe5b5b6001016102e6565b600192505b505093925050505600a165627a7a72305820763d8bfb0eb7d6bc9acfa299ea0a327f3f3ec61cce677a66aded01ffcdd48f420029", 56 | "networks": { 57 | "1": { 58 | "events": {}, 59 | "links": {}, 60 | "address": "0x53a30b07bea5b8e9b5f710e038867a1531b0b5dc", 61 | "updated_at": 1505297153002 62 | }, 63 | "42": { 64 | "events": {}, 65 | "links": {}, 66 | "address": "0xa2eda3fbf3774b88b06870c93a74f78c61110f5f", 67 | "updated_at": 1505292076768 68 | } 69 | }, 70 | "schema_version": "0.0.5", 71 | "updated_at": 1505297228083 72 | } -------------------------------------------------------------------------------- /build/contracts/Ownable.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Ownable", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "owner", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "address" 12 | } 13 | ], 14 | "payable": false, 15 | "stateMutability": "view", 16 | "type": "function" 17 | }, 18 | { 19 | "constant": false, 20 | "inputs": [ 21 | { 22 | "name": "newOwner", 23 | "type": "address" 24 | } 25 | ], 26 | "name": "transferOwnership", 27 | "outputs": [], 28 | "payable": false, 29 | "stateMutability": "nonpayable", 30 | "type": "function" 31 | }, 32 | { 33 | "inputs": [], 34 | "payable": false, 35 | "stateMutability": "nonpayable", 36 | "type": "constructor" 37 | } 38 | ], 39 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b6101218061003c6000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416638da5cb5b81146046578063f2fde38b146072575b600080fd5b3415605057600080fd5b60566090565b604051600160a060020a03909116815260200160405180910390f35b3415607c57600080fd5b608e600160a060020a0360043516609f565b005b600054600160a060020a031681565b60005433600160a060020a0390811691161460b957600080fd5b600160a060020a0381161560f0576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b505600a165627a7a72305820c2b95ec7be7d521ddcf3fe48652d8335c3f337f3728d58c425c47f2295318a860029", 40 | "networks": {}, 41 | "schema_version": "0.0.5", 42 | "updated_at": 1505289116288 43 | } -------------------------------------------------------------------------------- /build/contracts/SafeMath.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "SafeMath", 3 | "abi": [], 4 | "unlinked_binary": "0x60606040523415600e57600080fd5b5b603680601c6000396000f30060606040525b600080fd00a165627a7a7230582093ac0cf6e81c21726e39a54932cd27f581bd46f233acdf08e5030f3f385a039b0029", 5 | "networks": {}, 6 | "schema_version": "0.0.5", 7 | "updated_at": 1505289116288 8 | } -------------------------------------------------------------------------------- /build/contracts/StandardToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "StandardToken", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [ 7 | { 8 | "name": "_spender", 9 | "type": "address" 10 | }, 11 | { 12 | "name": "_value", 13 | "type": "uint256" 14 | } 15 | ], 16 | "name": "approve", 17 | "outputs": [ 18 | { 19 | "name": "", 20 | "type": "bool" 21 | } 22 | ], 23 | "payable": false, 24 | "stateMutability": "nonpayable", 25 | "type": "function" 26 | }, 27 | { 28 | "constant": true, 29 | "inputs": [], 30 | "name": "totalSupply", 31 | "outputs": [ 32 | { 33 | "name": "", 34 | "type": "uint256" 35 | } 36 | ], 37 | "payable": false, 38 | "stateMutability": "view", 39 | "type": "function" 40 | }, 41 | { 42 | "constant": false, 43 | "inputs": [ 44 | { 45 | "name": "_from", 46 | "type": "address" 47 | }, 48 | { 49 | "name": "_to", 50 | "type": "address" 51 | }, 52 | { 53 | "name": "_value", 54 | "type": "uint256" 55 | } 56 | ], 57 | "name": "transferFrom", 58 | "outputs": [ 59 | { 60 | "name": "", 61 | "type": "bool" 62 | } 63 | ], 64 | "payable": false, 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | }, 68 | { 69 | "constant": true, 70 | "inputs": [ 71 | { 72 | "name": "_owner", 73 | "type": "address" 74 | } 75 | ], 76 | "name": "balanceOf", 77 | "outputs": [ 78 | { 79 | "name": "balance", 80 | "type": "uint256" 81 | } 82 | ], 83 | "payable": false, 84 | "stateMutability": "view", 85 | "type": "function" 86 | }, 87 | { 88 | "constant": false, 89 | "inputs": [ 90 | { 91 | "name": "_to", 92 | "type": "address" 93 | }, 94 | { 95 | "name": "_value", 96 | "type": "uint256" 97 | } 98 | ], 99 | "name": "transfer", 100 | "outputs": [ 101 | { 102 | "name": "", 103 | "type": "bool" 104 | } 105 | ], 106 | "payable": false, 107 | "stateMutability": "nonpayable", 108 | "type": "function" 109 | }, 110 | { 111 | "constant": true, 112 | "inputs": [ 113 | { 114 | "name": "_owner", 115 | "type": "address" 116 | }, 117 | { 118 | "name": "_spender", 119 | "type": "address" 120 | } 121 | ], 122 | "name": "allowance", 123 | "outputs": [ 124 | { 125 | "name": "remaining", 126 | "type": "uint256" 127 | } 128 | ], 129 | "payable": false, 130 | "stateMutability": "view", 131 | "type": "function" 132 | }, 133 | { 134 | "anonymous": false, 135 | "inputs": [ 136 | { 137 | "indexed": true, 138 | "name": "owner", 139 | "type": "address" 140 | }, 141 | { 142 | "indexed": true, 143 | "name": "spender", 144 | "type": "address" 145 | }, 146 | { 147 | "indexed": false, 148 | "name": "value", 149 | "type": "uint256" 150 | } 151 | ], 152 | "name": "Approval", 153 | "type": "event" 154 | }, 155 | { 156 | "anonymous": false, 157 | "inputs": [ 158 | { 159 | "indexed": true, 160 | "name": "from", 161 | "type": "address" 162 | }, 163 | { 164 | "indexed": true, 165 | "name": "to", 166 | "type": "address" 167 | }, 168 | { 169 | "indexed": false, 170 | "name": "value", 171 | "type": "uint256" 172 | } 173 | ], 174 | "name": "Transfer", 175 | "type": "event" 176 | } 177 | ], 178 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b6104da8061001f6000396000f300606060405236156100755763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663095ea7b3811461007a57806318160ddd146100b057806323b872dd146100d557806370a0823114610111578063a9059cbb14610142578063dd62ed3e14610178575b600080fd5b341561008557600080fd5b61009c600160a060020a03600435166024356101af565b604051901515815260200160405180910390f35b34156100bb57600080fd5b6100c3610256565b60405190815260200160405180910390f35b34156100e057600080fd5b61009c600160a060020a036004358116906024351660443561025c565b604051901515815260200160405180910390f35b341561011c57600080fd5b6100c3600160a060020a0360043516610371565b60405190815260200160405180910390f35b341561014d57600080fd5b61009c600160a060020a0360043516602435610390565b604051901515815260200160405180910390f35b341561018357600080fd5b6100c3600160a060020a0360043581169060243516610450565b60405190815260200160405180910390f35b60008115806101e15750600160a060020a03338116600090815260026020908152604080832093871683529290522054155b15156101ec57600080fd5b600160a060020a03338116600081815260026020908152604080832094881680845294909152908190208590557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b60005481565b600160a060020a0380841660009081526002602090815260408083203385168452825280832054938616835260019091528120549091906102a3908463ffffffff61047d16565b600160a060020a0380861660009081526001602052604080822093909355908716815220546102d8908463ffffffff61049716565b600160a060020a038616600090815260016020526040902055610301818463ffffffff61049716565b600160a060020a03808716600081815260026020908152604080832033861684529091529081902093909355908616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9086905190815260200160405180910390a3600191505b509392505050565b600160a060020a0381166000908152600160205260409020545b919050565b600160a060020a0333166000908152600160205260408120546103b9908363ffffffff61049716565b600160a060020a0333811660009081526001602052604080822093909355908516815220546103ee908363ffffffff61047d16565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060015b92915050565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b60008282018381101561048c57fe5b8091505b5092915050565b6000828211156104a357fe5b508082035b929150505600a165627a7a7230582019cc650c31653c1d0ec348e042c9a02c44a5bbfc3ef71b318c1073d9e197f54f0029", 179 | "networks": {}, 180 | "schema_version": "0.0.5", 181 | "updated_at": 1505289116288 182 | } -------------------------------------------------------------------------------- /build/contracts/TestMintableToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "TestMintableToken", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "mintingFinished", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "bool" 12 | } 13 | ], 14 | "payable": false, 15 | "stateMutability": "view", 16 | "type": "function" 17 | }, 18 | { 19 | "constant": false, 20 | "inputs": [ 21 | { 22 | "name": "_spender", 23 | "type": "address" 24 | }, 25 | { 26 | "name": "_value", 27 | "type": "uint256" 28 | } 29 | ], 30 | "name": "approve", 31 | "outputs": [ 32 | { 33 | "name": "", 34 | "type": "bool" 35 | } 36 | ], 37 | "payable": false, 38 | "stateMutability": "nonpayable", 39 | "type": "function" 40 | }, 41 | { 42 | "constant": true, 43 | "inputs": [], 44 | "name": "totalSupply", 45 | "outputs": [ 46 | { 47 | "name": "", 48 | "type": "uint256" 49 | } 50 | ], 51 | "payable": false, 52 | "stateMutability": "view", 53 | "type": "function" 54 | }, 55 | { 56 | "constant": false, 57 | "inputs": [ 58 | { 59 | "name": "_from", 60 | "type": "address" 61 | }, 62 | { 63 | "name": "_to", 64 | "type": "address" 65 | }, 66 | { 67 | "name": "_value", 68 | "type": "uint256" 69 | } 70 | ], 71 | "name": "transferFrom", 72 | "outputs": [ 73 | { 74 | "name": "", 75 | "type": "bool" 76 | } 77 | ], 78 | "payable": false, 79 | "stateMutability": "nonpayable", 80 | "type": "function" 81 | }, 82 | { 83 | "constant": false, 84 | "inputs": [ 85 | { 86 | "name": "_to", 87 | "type": "address" 88 | }, 89 | { 90 | "name": "_amount", 91 | "type": "uint256" 92 | } 93 | ], 94 | "name": "mint", 95 | "outputs": [ 96 | { 97 | "name": "", 98 | "type": "bool" 99 | } 100 | ], 101 | "payable": false, 102 | "stateMutability": "nonpayable", 103 | "type": "function" 104 | }, 105 | { 106 | "constant": true, 107 | "inputs": [ 108 | { 109 | "name": "_owner", 110 | "type": "address" 111 | } 112 | ], 113 | "name": "balanceOf", 114 | "outputs": [ 115 | { 116 | "name": "balance", 117 | "type": "uint256" 118 | } 119 | ], 120 | "payable": false, 121 | "stateMutability": "view", 122 | "type": "function" 123 | }, 124 | { 125 | "constant": false, 126 | "inputs": [], 127 | "name": "finishMinting", 128 | "outputs": [ 129 | { 130 | "name": "", 131 | "type": "bool" 132 | } 133 | ], 134 | "payable": false, 135 | "stateMutability": "nonpayable", 136 | "type": "function" 137 | }, 138 | { 139 | "constant": true, 140 | "inputs": [], 141 | "name": "owner", 142 | "outputs": [ 143 | { 144 | "name": "", 145 | "type": "address" 146 | } 147 | ], 148 | "payable": false, 149 | "stateMutability": "view", 150 | "type": "function" 151 | }, 152 | { 153 | "constant": false, 154 | "inputs": [ 155 | { 156 | "name": "_to", 157 | "type": "address" 158 | }, 159 | { 160 | "name": "_value", 161 | "type": "uint256" 162 | } 163 | ], 164 | "name": "transfer", 165 | "outputs": [ 166 | { 167 | "name": "", 168 | "type": "bool" 169 | } 170 | ], 171 | "payable": false, 172 | "stateMutability": "nonpayable", 173 | "type": "function" 174 | }, 175 | { 176 | "constant": true, 177 | "inputs": [ 178 | { 179 | "name": "_owner", 180 | "type": "address" 181 | }, 182 | { 183 | "name": "_spender", 184 | "type": "address" 185 | } 186 | ], 187 | "name": "allowance", 188 | "outputs": [ 189 | { 190 | "name": "remaining", 191 | "type": "uint256" 192 | } 193 | ], 194 | "payable": false, 195 | "stateMutability": "view", 196 | "type": "function" 197 | }, 198 | { 199 | "constant": false, 200 | "inputs": [ 201 | { 202 | "name": "newOwner", 203 | "type": "address" 204 | } 205 | ], 206 | "name": "transferOwnership", 207 | "outputs": [], 208 | "payable": false, 209 | "stateMutability": "nonpayable", 210 | "type": "function" 211 | }, 212 | { 213 | "anonymous": false, 214 | "inputs": [ 215 | { 216 | "indexed": true, 217 | "name": "to", 218 | "type": "address" 219 | }, 220 | { 221 | "indexed": false, 222 | "name": "amount", 223 | "type": "uint256" 224 | } 225 | ], 226 | "name": "Mint", 227 | "type": "event" 228 | }, 229 | { 230 | "anonymous": false, 231 | "inputs": [], 232 | "name": "MintFinished", 233 | "type": "event" 234 | }, 235 | { 236 | "anonymous": false, 237 | "inputs": [ 238 | { 239 | "indexed": true, 240 | "name": "owner", 241 | "type": "address" 242 | }, 243 | { 244 | "indexed": true, 245 | "name": "spender", 246 | "type": "address" 247 | }, 248 | { 249 | "indexed": false, 250 | "name": "value", 251 | "type": "uint256" 252 | } 253 | ], 254 | "name": "Approval", 255 | "type": "event" 256 | }, 257 | { 258 | "anonymous": false, 259 | "inputs": [ 260 | { 261 | "indexed": true, 262 | "name": "from", 263 | "type": "address" 264 | }, 265 | { 266 | "indexed": true, 267 | "name": "to", 268 | "type": "address" 269 | }, 270 | { 271 | "indexed": false, 272 | "name": "value", 273 | "type": "uint256" 274 | } 275 | ], 276 | "name": "Transfer", 277 | "type": "event" 278 | } 279 | ], 280 | "unlinked_binary": "0x60606040526003805460a060020a60ff02191690555b60038054600160a060020a03191633600160a060020a03161790555b5b6107d6806100416000396000f300606060405236156100ac5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166305d2035b81146100b1578063095ea7b3146100d857806318160ddd1461010e57806323b872dd1461013357806340c10f191461016f57806370a08231146101a55780637d64bcb4146101d65780638da5cb5b146101fd578063a9059cbb1461022c578063dd62ed3e14610262578063f2fde38b14610299575b600080fd5b34156100bc57600080fd5b6100c46102ba565b604051901515815260200160405180910390f35b34156100e357600080fd5b6100c4600160a060020a03600435166024356102db565b604051901515815260200160405180910390f35b341561011957600080fd5b610121610382565b60405190815260200160405180910390f35b341561013e57600080fd5b6100c4600160a060020a0360043581169060243516604435610388565b604051901515815260200160405180910390f35b341561017a57600080fd5b6100c4600160a060020a036004351660243561049d565b604051901515815260200160405180910390f35b34156101b057600080fd5b610121600160a060020a036004351661057f565b60405190815260200160405180910390f35b34156101e157600080fd5b6100c461059e565b604051901515815260200160405180910390f35b341561020857600080fd5b610210610625565b604051600160a060020a03909116815260200160405180910390f35b341561023757600080fd5b6100c4600160a060020a0360043516602435610634565b604051901515815260200160405180910390f35b341561026d57600080fd5b610121600160a060020a03600435811690602435166106f4565b60405190815260200160405180910390f35b34156102a457600080fd5b6102b8600160a060020a0360043516610721565b005b60035474010000000000000000000000000000000000000000900460ff1681565b600081158061030d5750600160a060020a03338116600090815260026020908152604080832093871683529290522054155b151561031857600080fd5b600160a060020a03338116600081815260026020908152604080832094881680845294909152908190208590557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b60005481565b600160a060020a0380841660009081526002602090815260408083203385168452825280832054938616835260019091528120549091906103cf908463ffffffff61077916565b600160a060020a038086166000908152600160205260408082209390935590871681522054610404908463ffffffff61079316565b600160a060020a03861660009081526001602052604090205561042d818463ffffffff61079316565b600160a060020a03808716600081815260026020908152604080832033861684529091529081902093909355908616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9086905190815260200160405180910390a3600191505b509392505050565b60035460009033600160a060020a039081169116146104bb57600080fd5b60035474010000000000000000000000000000000000000000900460ff16156104e357600080fd5b6000546104f6908363ffffffff61077916565b6000908155600160a060020a038416815260016020526040902054610521908363ffffffff61077916565b600160a060020a0384166000818152600160205260409081902092909255907f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968859084905190815260200160405180910390a25060015b5b5b92915050565b600160a060020a0381166000908152600160205260409020545b919050565b60035460009033600160a060020a039081169116146105bc57600080fd5b6003805474ff00000000000000000000000000000000000000001916740100000000000000000000000000000000000000001790557fae5184fba832cb2b1f702aca6117b8d265eaf03ad33eb133f19dde0f5920fa0860405160405180910390a15060015b5b90565b600354600160a060020a031681565b600160a060020a03331660009081526001602052604081205461065d908363ffffffff61079316565b600160a060020a033381166000908152600160205260408082209390935590851681522054610692908363ffffffff61077916565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060015b92915050565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b60035433600160a060020a0390811691161461073c57600080fd5b600160a060020a03811615610774576003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b5b50565b60008282018381101561078857fe5b8091505b5092915050565b60008282111561079f57fe5b508082035b929150505600a165627a7a72305820bf20116f965e3174164a10857b8e2a4b061f4c4f117f1259be2efe7a6857a87f0029", 281 | "networks": {}, 282 | "schema_version": "0.0.5", 283 | "updated_at": 1505289116288 284 | } -------------------------------------------------------------------------------- /contracts/ERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.16; 2 | 3 | contract ERC20 { 4 | function transferFrom( address from, address to, uint value) returns (bool ok); 5 | } 6 | -------------------------------------------------------------------------------- /contracts/Multiplexer.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.16; 2 | 3 | import './ERC20.sol'; 4 | 5 | /// @title Multiplexer 6 | /// @author Chris Hitchcott 7 | /// :repository https://github.com/DigixGlobal/multiplexer 8 | 9 | contract Multiplexer { 10 | 11 | function sendEth(address[] _to, uint256[] _value) payable returns (bool _success) { 12 | // input validation 13 | assert(_to.length == _value.length); 14 | assert(_to.length <= 255); 15 | // count values for refunding sender 16 | uint256 beforeValue = msg.value; 17 | uint256 afterValue = 0; 18 | // loop through to addresses and send value 19 | for (uint8 i = 0; i < _to.length; i++) { 20 | afterValue = afterValue + _value[i]; 21 | assert(_to[i].send(_value[i])); 22 | } 23 | // send back remaining value to sender 24 | uint256 remainingValue = beforeValue - afterValue; 25 | if (remainingValue > 0) { 26 | assert(msg.sender.send(remainingValue)); 27 | } 28 | return true; 29 | } 30 | 31 | function sendErc20(address _tokenAddress, address[] _to, uint256[] _value) returns (bool _success) { 32 | // input validation 33 | assert(_to.length == _value.length); 34 | assert(_to.length <= 255); 35 | // use the erc20 abi 36 | ERC20 token = ERC20(_tokenAddress); 37 | // loop through to addresses and send value 38 | for (uint8 i = 0; i < _to.length; i++) { 39 | assert(token.transferFrom(msg.sender, _to[i], _value[i]) == true); 40 | } 41 | return true; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /contracts/TestMintableToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.11; 2 | 3 | import 'zeppelin-solidity/contracts/token/MintableToken.sol'; 4 | 5 | contract TestMintableToken is MintableToken { } 6 | -------------------------------------------------------------------------------- /migrations/1_deploy.js: -------------------------------------------------------------------------------- 1 | var Multiplexer = artifacts.require("./Multiplexer.sol"); 2 | 3 | module.exports = function(deployer) { 4 | if (process.env.RUN_SCRIPT) { return null; } 5 | deployer.deploy(Multiplexer); 6 | }; 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@hitchcott/multiplexer", 3 | "version": "0.0.1", 4 | "description": "Contract for sending ETH or ERC20 to multiple addresses in one transaction", 5 | "scripts": { 6 | "test": "truffle test", 7 | "script": "RUN_SCRIPT='true' truffle test ./test/RunScriptWithWorkingWeb3.js --network mainnet" 8 | }, 9 | "devDependencies": { 10 | "@digix/truffle-lightwallet-provider": "^0.1.2", 11 | "awaiting": "^3.0.0", 12 | "babel-eslint": "^7.2.3", 13 | "babel-preset-env": "^1.6.0", 14 | "babel-preset-stage-0": "^6.24.1", 15 | "eslint": "^4.6.1", 16 | "eslint-config-airbnb": "^15.1.0", 17 | "eslint-plugin-import": "^2.7.0", 18 | "eslint-plugin-jsx-a11y": "^5.1.1", 19 | "eslint-plugin-react": "^7.3.0", 20 | "zeppelin-solidity": "^1.2.0" 21 | }, 22 | "author": "", 23 | "license": "ISC" 24 | } 25 | -------------------------------------------------------------------------------- /scripts/dgd-reward.js: -------------------------------------------------------------------------------- 1 | const Multiplexer = artifacts.require('./Multiplexer.sol'); 2 | const multiplexer = Multiplexer.at(Multiplexer.address); 3 | 4 | console.log('Multiplex Address', Multiplexer.address); 5 | 6 | const ERC20 = artifacts.require('./TestMintableToken.sol'); 7 | const token = ERC20.at('0xe0b7927c4af23765cb51314a0e0521a9645f0e2a'); 8 | const tokenWeiPerAddress = 100000000; 9 | const addresses = [ 10 | '0xc9281a5609b232a6c5ad610c635d552c14f51a9a', 11 | '0x67436a2c32f8e72e9de5bcf1b5f6fff8172d4ad2', 12 | '0xa61b8d13d20a3bddf00702bfe4092981701a7358', 13 | '0xee90ce56e68b011fc1b9e84aac62156b8c27763f', 14 | '0xc2b82e7db33d926ebfc1d92f45a9b234e531b67b', 15 | '0xfca73eff8771c0103ba3cc1a9c259448c72abf0b', 16 | '0x002ffa6895c01838107153adf84c2978166a220f', 17 | '0x79e063a8288dffb4156f42210d765b975aeb0957', 18 | '0x2c34f01fe0fe83fa047c7d891ab661a4cbf882af', 19 | '0x64d683a2cafe27181a30cfe229336cc87bcb5f41', 20 | '0x4a4d417a4766113b8dff28473af6ea401fd23d57', 21 | '0x1fb6bfc715831378def113c9e54122b43842b3cb', 22 | '0xd70e7ae5bfd1bd4561b5bac445d5022b16d5440f', 23 | '0x53c8f3032a89baae2dd8bfd426660775a00efaf3', 24 | '0xe13cec7b2c10574e5e89a780582b66d2c3c71b80', 25 | '0xf58499644d1d27c04df2f1191c4cfe2620a98b5c', 26 | '0x9efe2a4863c1a134667a26deff65490a1cabf687', 27 | '0xea7ec11702a8a13ee56fe0e3742cd35f0c1d3cf9', 28 | '0xff6ef346d8e6c0612a129f135b107123bea60f2b', 29 | '0xa592d5e6134abbdb05f18159331045460d22ae19', 30 | '0x2397c5a2c15ee5224bb3a1bdd902695b15059689', 31 | '0x146764a316ec64237ef6a20bc663b1b276e27c02', 32 | '0x29b2d45dbd7ce98aa9303e31e715b45b94ccfcfa', 33 | '0x00942a25b32de6fc88ef056610aed3ec677966a4', 34 | '0x133d5cb0506fb3406a7fcb0da80636af8755bf63', 35 | '0x2da3f6e73cf65064c2ed31cbbae4e39f0e3c3c04', 36 | '0xff6590510f959b93754d8e399b5b6a0c9c5ba2fc', 37 | '0x5592c1d00d3024bdeb0e5cd5a6096edde5bd2838', 38 | '0xb074278ef8a4612ec0a0d5387447857f1097a157', 39 | '0x33661b5d68c274dea912e801837968abbadeff7e', 40 | '0x00fefa26320ab4ab6ec67bddccc92cf0d7d2d0fb', 41 | '0x5b0733b9adb031c580493b88cdd52f761c195da0', 42 | '0x9c1478134d61258dd2c35de561bd0ff94678ab5e', 43 | '0xbb88dac0ae203632bb5ec80c00fbb6f5d82ec974', 44 | '0x65870575837f98511793041ee5c0cc4db911b01e', 45 | '0x1bcfe4f499db23909a5ddc33d6e2d879531176ec', 46 | '0xafe54cd3dc41336e769096f6ea8080a682a3d9e2', 47 | '0x7205fc2ec03ae1109b35d983407a223ac82c4871', 48 | '0xdae48d7b5c73a95f74caae08f7f92d3b7927f449', 49 | '0xd122d84d5bc9da9a307050019358f6cc4cc6d8fb', 50 | '0xc597044ed3da76cab487f730df41c5d7bad4feb9', 51 | '0x1b00e80c64164c76299157bd5723deb184b0c6d0', 52 | '0x02b1295c5b7d3aa02669f542634f66462b8c9abf', 53 | '0x2a477f1f93d17457a23ba72368743c4b1bff2a28', 54 | '0x1c82ccd574044df0318e039b5d7d9f1f84685e61', 55 | '0x19a588c4867a91402dd3e9d477212289cf9aeca9', 56 | '0xd1ebae724248cb8a14483c6987feeb6c928d8172', 57 | '0x0b450b9d5a9769a6f7adbd8dc2dda0dfb47c5c3a', 58 | '0x63812dbd7d5665e00f92c8e73b36e49fe1b15743', 59 | '0x6375325cb611dee5208499e8296ee640e32dfd18', 60 | '0xf881e5f99a448b95954028071dcb24153381ee74', 61 | '0xe34c208f1d1d10d07e9e948455c64f69d6e6d838', 62 | '0x87c280c758aa49b6aefeeec7257a1de7e8a54214', 63 | '0xc85cf7e6a0cd95abb46d4e6048d7e5c0c6e85205', 64 | '0x3f474cab8fa6f861bb533a70e10c3e944cb0b410', 65 | '0xb55cb753291d726d620502c10843f265e447a6fe', 66 | '0x98c80268276ac6306f27b6430c49e8d0473d753d', 67 | '0xfc5bbc2bbe5fb0a9e2665a7a9f2290ee34d3c64e', 68 | '0x7f2b9a08f35b7b4de85354260f4540302ce1877e', 69 | '0x74e74d0194286014b500186e6224b088153da54e', 70 | '0x5814ba8ac95575318c8f1692dd2f7b687d07b821', 71 | '0xa5da57311bc233b112ab817c732804d2a4c0297c', 72 | '0xdcab44b6fda7d1e0ef6f9d9ead6508e0e1558264', 73 | '0x3af76d7e196322ce4f62dfefedd5778e12df7eaa', 74 | '0xbb1965f10fe59ef9df35be181945d9538eb798b6', 75 | '0x56446712b219fcc34a5604f5e7af5d50d65b6647', 76 | '0x90a64ed7b118631520ac1d71f348ff213ca51817', 77 | '0x45a4175d7cb99dd229aa51c059c68c27adcb94db', 78 | '0xa59a170fa8ae723fd9962e7b72aa1fdb01e90608', 79 | '0xe7c613dd9f8658205556c89f042dcdc7e10c23a0', 80 | '0xf9a8aa349a7774d25a4af1815c24494389995cb8', 81 | '0x9c1363e8a8dac64147c3e5e6533dacf269471247', 82 | '0x51c61b0b86d1c2a742c30b188dcf82acbc9fb09b', 83 | '0x3cc03e1a54f2255beb485187d75a66fb5a574593', 84 | '0x9b422e571eb2cb9837efdc4f9087194d65fb070a', 85 | '0x9b8ab4aaf18f4ea4b18a954462b53469b2dc4b84', 86 | '0x5b237a7cb07c71f4bbe7a4706c7540f76954fde2', 87 | '0xd82811fd89f18a6361286bf7501f5464edb3b789', 88 | '0x9230ad3c01fc8c1929644af5bd360d5115623ddb', 89 | '0x4163eb44702bea470431db626091e310575244ef', 90 | '0xbeb1fd865feea5006c74bcb615ebb00f1a05d469', 91 | '0x1a6e2f78cf14939864b8a701a28eeedf62d9a952', 92 | '0x2a3d46aa866d1be217e33455732948faff9a45b4', 93 | '0x7997894f43112be3bc1c57a910a12b0a350fcf28', 94 | '0x8c0a0ba507ce136c29ec050781ee80697a06e3e9', 95 | '0x2f2b0ea87b0ac0546efa511a5e9c6423e0d9a699', 96 | '0x2947f743dd35f2206098e18a9b3a3928d05d293f', 97 | '0x7b1b26bf04b5b6e1e78f4d105e5726205458b4ef', 98 | '0xe54a5487ea8816559d88eabf26b783fe343eda49', 99 | '0x69017e33796601bf924805b4c5fdb14b0ca7f064', 100 | '0x114f7a44cd8b68ca3841340f1ea54dcece073f5f', 101 | '0x62eca0fb900a26695dd6c0a4fe719987307d4eae', 102 | '0xa297a4d809e4681fbcfbcdfbf389abce02e39d15', 103 | '0xe43e41b65400c8f5da681feb34710bd7552b95de', 104 | '0x1efb00cca7e2b858fcb42f522a400cc77b74783f', 105 | '0xf30bc8ab61e7719961bc9cd4ff1af0f3d62e6d44', 106 | '0xd9486aa30e2e4cc3d4c7145d32b8bc0f365b506a', 107 | '0xc12fd6bf9cb58c76aebf57d3051b869a434e7d26', 108 | '0xfe7fb7f348336508130973ca872251541bb92cd1', 109 | '0x908f47089c11b4a1ee452bd4b72efa244601835e', 110 | '0x1c6f4dfc666da461a42e9b5d890c1d1ec5c6ba16', 111 | '0xfdd01842b99e96dfb0c58d28ecf755c933f3d1d2', 112 | '0x24ab5e1fc2925e54a505ed9fa52b29ee019d2764', 113 | '0xfec13845ea2cb90757501bab2284f378fd20aec2', 114 | '0x34b90a87882d4dc26fac53ea8a5d57938783bcf2', 115 | '0xf1713729be985a4d42730a6884890fe7be9596d0', 116 | '0x72af8296d1272deffe909926d1db18ee418542a8', 117 | '0x0ccd062e8a71fa30a74d06f353db199e5657b6e6', 118 | '0x9dbaee36c621e6c13cf1875fda1ee851940b202e', 119 | '0x882249acdd6f2e0ed067e5c66a6667baa7386b38', 120 | '0xaa4eb3b318e0bf21ad42a6799478ab7f4c634ffe', 121 | '0x36d04a65fb975e4ff71949eb8b568ffb01bd1e15', 122 | '0x14730014eea880f2d52ac0b67442c485242d9b9c', 123 | '0xf7dbc54d3fbba3f1ed9881ae539f1c65d8bce166', 124 | '0xd929ad1e45b7963bf98bb25bcbd3e6db858e9f45', 125 | '0xdae300f0627e35a17f2dfcaac6fda998e393b7d0', 126 | '0xcc9e7ce4c5423abcc24af376ae1a7f456d7b440d', 127 | '0x6fb7f22e5b989004ea1691fcb7ac61cf2df1e3d0', 128 | '0xf1f0c294d247e8691d1118a86ccc669da3c75ca8', 129 | '0x70764718f4f9ac8d5c3691781ebb030e3d6d0444', 130 | '0x65af03a3825d186cdae0296e4bbb4c843b9c1559', 131 | '0xd487ee360225e0a01b32615e0c24798b42860266', 132 | '0xc86e32838e72e728c93296b0ef11303b3d97a7a7', 133 | '0xb17391eb239387c225c481245355299ea3a9c17f', 134 | '0x2253c1f60648cf6190a349d2453c549555feca10', 135 | '0x5bba175464707a3eb9465e12379f7fda215242ab', 136 | '0xb3ddf32ff40efdece57a620c071cd0437e0277fb', 137 | '0x3027a0ef7693523e0f59e843f5faf2259c54e728', 138 | '0xf86a1a041cea941e78af95f4f11179c056b1c817', 139 | '0x3cf2b135b6aa323a5989f7902a806b055bf05649', 140 | '0x061d9764142f8277954c80c610d30b58aae08cdc', 141 | '0xf616b3fc9d272a064d098be6722f7b3dac5022ba', 142 | '0x02e92cc5aff51dbac02fad20c54949dcefca7e28', 143 | ]; 144 | const balances = addresses.map(() => tokenWeiPerAddress); 145 | const total = balances.reduce((t, n) => t + n, 0); 146 | 147 | module.exports = async () => { 148 | console.log(`Sending ${total} token wei`); 149 | // console.log('Setting new allowance', await token.approve(multiplexer.address, total, { gas: 6000000, gasPrice: 12e9 })); 150 | console.log('Sending', await multiplexer.sendErc20(token.address, addresses, balances, { gas: 6000000, gasPrice: 12e9 })); 151 | }; 152 | -------------------------------------------------------------------------------- /test/Multiplexer.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable max-len */ 2 | const crypto = require('crypto'); 3 | 4 | const Multiplexer = artifacts.require('./Multiplexer.sol'); 5 | const ERC20 = artifacts.require('./TestMintableToken.sol'); 6 | 7 | const bn = web3.toBigNumber; 8 | 9 | function getBalance(address) { 10 | return new Promise((resolve) => { 11 | web3.eth.getBalance(address, (e, res) => resolve(res)); 12 | }); 13 | } 14 | 15 | function getBalances(addresses) { 16 | return Promise.all(addresses.map(getBalance)); 17 | } 18 | 19 | function getTokenBalance(token, address) { 20 | return token.balanceOf.call(address); 21 | } 22 | 23 | function getTokenBalances(token, addresses) { 24 | return Promise.all(addresses.map(a => getTokenBalance(token, a))); 25 | } 26 | 27 | 28 | function randomAddress() { 29 | return `0x${crypto.randomBytes(20).toString('hex')}`; 30 | } 31 | 32 | function randomAddresses(n) { 33 | return Array(n).fill().map(randomAddress); 34 | } 35 | 36 | contract('Multiplexer', ([from]) => { 37 | let multiplexer; 38 | before(async () => { 39 | multiplexer = await Multiplexer.new(); 40 | }); 41 | describe('sendEth', () => { 42 | it('sends to a few users', async () => { 43 | const amounts = [1, 2, 3]; 44 | const value = amounts.reduce((n, a) => n + a, 0); 45 | const recipients = randomAddresses(amounts.length); 46 | const before = await getBalances(recipients); 47 | await multiplexer.sendEth(recipients, amounts, { value }); 48 | const after = await getBalances(recipients); 49 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i].add(amounts[i]))); 50 | assert.deepEqual(await getBalance(multiplexer.address), bn(0)); 51 | }); 52 | it('sends to a lot of users', async () => { 53 | const amounts = Array.from(Array(100).keys()); 54 | const value = amounts.reduce((n, a) => n + a, 0); 55 | const recipients = randomAddresses(amounts.length); 56 | const before = await getBalances(recipients); 57 | await multiplexer.sendEth(recipients, amounts, { value }); 58 | const after = await getBalances(recipients); 59 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i].add(amounts[i]))); 60 | assert.deepEqual(await getBalance(multiplexer.address), bn(0)); 61 | }); 62 | it('returns to sender when sending more value', async () => { 63 | const amounts = [1, 2, 3, 20]; 64 | const actualValue = amounts.reduce((n, a) => n + a, 0); 65 | const value = 200; 66 | const senderBalance = await getBalance(from); 67 | const recipients = randomAddresses(amounts.length); 68 | const before = await getBalances(recipients); 69 | const gasPrice = 4e9; 70 | const { receipt: { gasUsed } } = await multiplexer.sendEth(recipients, amounts, { value, gasPrice }); 71 | const gasCost = gasPrice * gasUsed; 72 | const after = await getBalances(recipients); 73 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i].add(amounts[i]))); 74 | assert.deepEqual(await getBalance(multiplexer.address), bn(0)); 75 | assert.deepEqual(await getBalance(from), senderBalance.sub(gasCost).minus(actualValue)); 76 | }); 77 | it('throws when sending to too many users (out of gas)', async () => { 78 | const amounts = Array.from(Array(200).keys()); 79 | const value = amounts.reduce((n, a) => n + a, 0); 80 | const recipients = randomAddresses(amounts.length); 81 | const before = await getBalances(recipients); 82 | let thrown = false; 83 | try { 84 | await multiplexer.sendEth(recipients, amounts, { value }); 85 | } catch (e) { 86 | thrown = true; 87 | } 88 | assert.equal(thrown, true); 89 | const after = await getBalances(recipients); 90 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i])); 91 | assert.deepEqual(await getBalance(multiplexer.address), bn(0)); 92 | }); 93 | it('throws when sending to too many users (greater than uint8)', async () => { 94 | const amounts = Array.from(Array(256).keys()); 95 | const value = amounts.reduce((n, a) => n + a, 0); 96 | const recipients = randomAddresses(amounts.length); 97 | const before = await getBalances(recipients); 98 | let thrown = false; 99 | try { 100 | await multiplexer.sendEth(recipients, amounts, { value }); 101 | } catch (e) { 102 | thrown = true; 103 | } 104 | assert.equal(thrown, true); 105 | const after = await getBalances(recipients); 106 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i])); 107 | assert.deepEqual(await getBalance(multiplexer.address), bn(0)); 108 | }); 109 | it('throws when not sending enough value', async () => { 110 | const amounts = [1, 2, 3]; 111 | const recipients = randomAddresses(amounts.length); 112 | const before = await getBalances(recipients); 113 | let thrown = false; 114 | try { 115 | await multiplexer.sendEth(recipients, amounts, { value: 3 }); 116 | } catch (e) { 117 | thrown = true; 118 | } 119 | assert.equal(thrown, true); 120 | const after = await getBalances(recipients); 121 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i])); 122 | assert.deepEqual(await getBalance(multiplexer.address), bn(0)); 123 | }); 124 | }); 125 | 126 | describe('sendErc20', () => { 127 | const initialTokens = 5000; 128 | let erc20; 129 | beforeEach(async () => { 130 | erc20 = await ERC20.new(); 131 | await erc20.mint(from, initialTokens); 132 | }); 133 | it('sends to a few users', async () => { 134 | const amounts = [1, 2, 3]; 135 | const value = amounts.reduce((n, a) => n + a, 0); 136 | const recipients = randomAddresses(amounts.length); 137 | const before = await getTokenBalances(erc20, recipients); 138 | await erc20.approve(multiplexer.address, value); 139 | await multiplexer.sendErc20(erc20.address, recipients, amounts); 140 | const after = await getTokenBalances(erc20, recipients); 141 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i].add(amounts[i]))); 142 | assert.deepEqual(await getTokenBalance(erc20, from), bn(initialTokens - value)); 143 | }); 144 | it('sends to a lot of users', async () => { 145 | const amounts = Array.from(Array(100).keys()); 146 | const value = amounts.reduce((n, a) => n + a, 0); 147 | const recipients = randomAddresses(amounts.length); 148 | const before = await getTokenBalances(erc20, recipients); 149 | await erc20.approve(multiplexer.address, value); 150 | await multiplexer.sendErc20(erc20.address, recipients, amounts); 151 | const after = await getTokenBalances(erc20, recipients); 152 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i].add(amounts[i]))); 153 | assert.deepEqual(await getTokenBalance(erc20, from), bn(initialTokens - value)); 154 | }); 155 | it('throws when sending to too many users (out of gas)', async () => { 156 | const amounts = Array.from(Array(200).keys()); 157 | const value = amounts.reduce((n, a) => n + a, 0); 158 | const recipients = randomAddresses(amounts.length); 159 | const before = await getTokenBalances(erc20, recipients); 160 | await erc20.approve(multiplexer.address, value); 161 | let thrown = false; 162 | try { 163 | await multiplexer.sendErc20(erc20.address, recipients, amounts); 164 | } catch (e) { 165 | thrown = true; 166 | } 167 | assert.equal(thrown, true); 168 | const after = await getBalances(recipients); 169 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i])); 170 | assert.deepEqual(await getTokenBalance(erc20, from), bn(initialTokens)); 171 | }); 172 | it('throws when sending to too many users (greater than uint8)', async () => { 173 | const amounts = Array.from(Array(256).keys()); 174 | const value = amounts.reduce((n, a) => n + a, 0); 175 | const recipients = randomAddresses(amounts.length); 176 | const before = await getTokenBalances(erc20, recipients); 177 | await erc20.approve(multiplexer.address, value); 178 | let thrown = false; 179 | try { 180 | await multiplexer.sendErc20(erc20.address, recipients, amounts); 181 | } catch (e) { 182 | thrown = true; 183 | } 184 | assert.equal(thrown, true); 185 | const after = await getBalances(recipients); 186 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i])); 187 | assert.deepEqual(await getTokenBalance(erc20, from), bn(initialTokens)); 188 | }); 189 | it('throws when not approved enough', async () => { 190 | const amounts = [1, 2, 3]; 191 | const recipients = randomAddresses(amounts.length); 192 | const before = await getTokenBalances(erc20, recipients); 193 | await erc20.approve(multiplexer.address, 2); 194 | let thrown = false; 195 | try { 196 | await multiplexer.sendErc20(erc20.address, recipients, amounts); 197 | } catch (e) { 198 | thrown = true; 199 | } 200 | assert.equal(thrown, true); 201 | const after = await getBalances(recipients); 202 | amounts.forEach((a, i) => assert.deepEqual(after[i], before[i])); 203 | assert.deepEqual(await getTokenBalance(erc20, from), bn(initialTokens)); 204 | }); 205 | }); 206 | }); 207 | -------------------------------------------------------------------------------- /test/RunScriptWithWorkingWeb3.js: -------------------------------------------------------------------------------- 1 | // i'm having to use this file to run the script.... 2 | // https://github.com/trufflesuite/truffle/issues/526 3 | 4 | // use: 5 | // RUN_SCRIPT='true' truffle test ./test/RunScriptWithWorkingWeb3.js 6 | // to make this work 7 | 8 | if (!process.env.RUN_SCRIPT) { return null; } 9 | 10 | require('../scripts/dgd-reward.js')(); 11 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | const LightWalletProvider = require('@digix/truffle-lightwallet-provider'); 3 | 4 | const { KEYSTORE, PASSWORD } = process.env; 5 | 6 | if (!KEYSTORE || !PASSWORD) { throw new Error('You must export KEYSTORE and PASSWORD (see truffle.js)'); } 7 | 8 | module.exports = { 9 | networks: { 10 | development: { 11 | host: 'localhost', 12 | port: 6545, 13 | network_id: '*', // Match any network id 14 | }, 15 | kovan: { 16 | provider: new LightWalletProvider({ 17 | keystore: KEYSTORE, 18 | password: PASSWORD, 19 | rpcUrl: 'https://kovan.infura.io/', 20 | pollingInterval: 2000, 21 | }), 22 | network_id: '42', 23 | }, 24 | mainnet: { 25 | provider: new LightWalletProvider({ 26 | keystore: KEYSTORE, 27 | password: PASSWORD, 28 | rpcUrl: 'https://mainnet.infura.io/', 29 | pollingInterval: 5000, 30 | }), 31 | gas: 350000, 32 | gasPrice: 5e9, 33 | network_id: '1', 34 | }, 35 | }, 36 | }; 37 | --------------------------------------------------------------------------------