-
Notifications
You must be signed in to change notification settings - Fork 23
Initial pass at converting from TruffleContract to Web3 #10
Conversation
24d74cb
to
b82ddcb
Compare
TruffleContract automatically calls estimateGas for many transactions. For Web3, it uses the gas estimates contained in the contract ABI's. Unfortunately, these gas estimates in the ABI's do not include estimation of calls to abstract contracts (interfaces of externals, eg. IBondedECDSAKeepVendor).
- using .returnValues instead of .args - setting defaultAccount for Deposit/Keep contract
This is more concise than the long lookup. web3-utils is installed as a peer dependency of the web3 package.
a3c4e8d
to
0addbb3
Compare
Manual merge based off a `git diff`. It was easier than messing around with rebase.
0addbb3
to
cacc5c5
Compare
For JS code that doesn't explictly declare its exports using ES6 Module Syntax (import/export), instead using CommonJS syntax (module.exports = xyz;), we can only import the default export. See this article for a good reference - https://medium.com/the-node-js-collection/an-update-on-es6-modules-in-node-js-42c958b890c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a long pass here. This mostly looks awesome, few remarks on things we can abstract better, couple of other improvements and tweaks that we can make separately.
return await this.systemContract.getAllowedLotSizes() | ||
return (await this.systemContract.methods.getAllowedLotSizes().call()).map( | ||
toBN | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does web3 return instead of BN
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the answer might be strings… If that's the case, I'm interested in using BigNumber
rather than BN
. tbtc-dapp already uses BigNumber
, and switching back and forth between that and BN
is a real pain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😬 Switching back-and-forth is a pain.
We do have inconsistent usage of big numbers:
- we use BigNumber 3x in
tbtc-dapp
and a handful of times intbtc
- we use BN 90% of the time in
tbtc
tests
Why BigNumber over BN? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BigNumber
supports decimal math, BN
only supports integers. BN
is more performant. Right tool for the right job, but I think for frontend stuff being able to do decimal math is a strong win---in the case of the dApp, it's necessary, since we do signing fee math and display values in TBTC, not tSats or whatever we want to call them 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, thought there was a reason 😉
Do you think it's a small amount of work? Wondering if I can get the hardware wallet stuff done first before we do this. dApp works currently without it.
Also tSats is palindromic, mmmmm I like it...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah let's handle this after.
const contract = new web3.eth.Contract(artifact.abi) | ||
contract.options.address = lookupAddress(artifact) | ||
contract.options.from = web3.eth.defaultAccount | ||
this[propertyName] = contract |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Crazy question here: do we want to store contract.methods
? I feel like that's the only thing we actually interact with anywhere, and it would make the remaining interactions much cleaner. If we did that we'd probably want to name the properties e.g. tokenMethods
, systemMethods
, depositTokenMethods
, etc, of course.
We probably still need access to the contract stuff for e.g. events, but I wonder if we don't invert the importance and give the *Methods
objects a .contract
property that references the contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, hadn't thought of that.
tokenMethods.balanceOf(address).call()
vs. .tokenContract.methods.balanceOf(address).call()
- how much cleaner does it seem? Moving in the direction of TruffleContract's API, I would want to remove .call
too, so it's as simple as tokenMethods.balanceOf(address)
.
My opinion - could focus on improving other aspects first.
@@ -94,25 +97,28 @@ export default class Redemption { | |||
"SignatureSubmitted", | |||
{ digest: redemptionDigest } | |||
) | |||
const { r, s, recoveryID } = signatureEvent.args | |||
const { r, s, recoveryID } = signatureEvent.returnValues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are r
and s
here not strings now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, they are? Confused as to what you're getting at.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I asked this here for some reason, but it's because below you toString
both of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. I think single byte256 words are converted into BN/buffer instances by the ABI decoder? Not sure, to be perfectly honest.
@@ -1,4 +1,5 @@ | |||
import { TX } from "bcoin/lib/primitives/index.js" | |||
import BcoinPrimitives from "bcoin/lib/primitives/index.js" | |||
const { TX } = BcoinPrimitives |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mentioned it in the commit description. GitHub doesn't surface this though :/
For JS code that doesn't explictly declare its exports using ES6 Module Syntax (import/export), instead using CommonJS syntax (module.exports = xyz;), we can only import the default export.
See this article for a good reference - https://medium.com/the-node-js-collection/an-update-on-es6-modules-in-node-js-42c958b890c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is… Strange. Our current code works fine, right? In the browser and on the command line with Node 12 latest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To get this running, I have to run:
$ nvm use v12
# node v12.0.0
$ node --experimental-modules --experimental-json-modules --async-stack-traces example-local.js
Without this modified import syntax, the error that is thrown is:
(node:42107) ExperimentalWarning: The ESM module loader is experimental.
(node:42107) ExperimentalWarning: Importing JSON modules is an experimental feature. This feature could change at any time
file:///Users/liamz/go/src/github.com/keep-network/tbtc.js/src/lib/BitcoinTxParser.js:3
import { TX } from "bcoin/lib/primitives/index.js"
^^
SyntaxError: The requested module 'bcoin/lib/primitives/index.js' does not provide an export named 'TX'
at ModuleJob._instantiate (internal/modules/esm/module_job.js:92:21)
at async ModuleJob.run (internal/modules/esm/module_job.js:107:20)
at async Loader.import (internal/modules/esm/loader.js:164:24)
```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be interested in seeing how you ran it @Shadowfiend - I should've asked before. 😸 For reference, node v10 with --harmony
wasn't working for me, but v12 was.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, v12 only, but never ran into this. Anyway, no need to block for now I guess.
This improves readability in the console.
This feels real close… Interested in figuring out why that change for I'm also interested in seeing a helper for the |
@Shadowfiend I'll do a follow-up for the 0x replacement tomorrow. 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oookay, let's land this!
This was broken after we swapped from TruffleContract to web3.js in keep-network/tbtc.js#10
This PR refactors our code to use Web3 as our library for interacting with contracts, replacing using of
TruffleContract
.Conversion notes
eg.