ethereum-contracts
Ethereum contracts wrapper which makes it easier to deploy contracts to the blockchain and invoke their methods.
Features:
- Automatically converts method arguments and return values according to types in contract ABI.
- Auto-fetches transaction receipts for
sendTransaction
calls. Promise
-ified asynchronous interface for easy use.- Errors are gracefully handled
- Customizable logging, can be turned on/off at runtime
- Works with any web3 instance
- No dependencies - works in Node, Electron apps and browsers
- Automated tests
Installation
$ npm install ethereum-contracts
Usage
Basic contract deployment:
;;; const web3 = /* connect to running Geth node */; // create a new factoryconst factory = web3: web3 /* Account from which to make transactions */ account: web3ethcoinbase /* Default gas to use for any transaction */ gas: 500000 ; // compile our contractconst soliditySrc = ;constant contractData = Object; // get Contract instanceconst contract = factory; // Deploy it!contract ;
The deploy()
method returns a Promise
which resolves to an instance of
ContractInstance
(require('ethereum-contracts').ContractInstance
)
representing an instance of the contract at its deployed address.
This instance exposes an API which by which you can methods within the deployed contract.
Note: If you get an error stating that your account is locked then you
may need to unlock it first using web3.personal.unlockAccount()
.
Invoking contract methods locally
Suppose we have a simple contract code:
contract Local { function getOne() returns (uint8, string) { return (123, "ok"); }}
We can call getOne()
on the local blockchain without having to send out a
transaction:
console; /* [ 123, "ok" ] */
Invoking contract methods via Transaction
Let's say our contract is:
contract Counter { uint8 val; function increment(){ val += 1; }}
We can invoke increment()
by sending a transaction to the blockchain, which returns a Promise
:
contractInstance;
The txReceipt
object returned above is the result of the call to
web3.eth.getTransactionReceipt()
for the corresponding transaction.
Passing in method arguments
Let's say we our contract is:
contract Counter { uint8 val; string label; function increment(uint8 amount, string newLabel) { val += amount; label = newLabel; } function isBigger(uint8 check) returns (bool) { return (check > val) ? true : false; }}
We can pass in arguments for both local calls and transaction calls as
key-value pairs (i.e. Object
):
// locallet result = contractInstance // transactioncontractInstance;
Override account and gas
Whether deploying a contract or calling a method via transaction, the gas value and account from which the transaction is sent can be overridden on a per-call basis:
; contract = web3: web3 contract: contractData account: web3ethcoinbase gas: 500000 contract
Browser usage
If you are not using a packaging manager and are instead importing ethereumContracts.js directly then the class is exposed on the global object as EthereumContracts
. Thus, in the browser window context you would use it like this:
const contractFactory = web3: web3 account: web3ethcoinbase gas: 500000;
Type conversions
When passing in method arguments the wrapper will try to type-cast each argument to the required target type as defined in the contract ABI.
Specifically, here is what it does for each type:
int/uint, int8/uint8, ..., int256/uint256
- input argument is converted to a number and then checked to ensure it is within the accepted range of numbers for the given type's boundaries. Note thatDate
instances get auto-converted to their millisecond representations.string
- input argument is converted to a string.bool
- if input argument is0, false, "false", or ""
it is passed on asfalse
else it is passed on astrue
.address
- if input argument is a number it is converted to a hex representation with enough padding to ensure it is a valid address. Otherwise it is string-ified and checked usingweb3.isAddress()
.byte, bytes, bytes, ..., bytes32
- input argument is converted to hex usingweb3.toHex()
.
For return values, the logic just ensures that int/uint
values are returned
as actual numbers and not BigNumber
instances (as is usually returned by web3).
Example
Let's say our contructor has:
contract Test { constructor(uint256 val, bool flag, address addr) {}}
If we deploy with the following arguments...
thiscontract;
...the actual values passed to the constructor will be:
(1451597422000, false, '0x00000000000000000000000000000000000392fa')
Development
To build and run the tests:
$ npm install$ npm test
To run tests with coverage:
$ npm run test-coverage
Contributions
Contributions welcome - see CONTRIBUTING.md
License
MIT - see LICENSE.md