Open jlstr opened 6 years ago
I am also interested in an answer to this.
@jlstr @jaramburu
First of all: Calling ABI functions is something I want to make MUCH easier than it is right now. I am currently designing something for it and you can track the development of it in #9
This does not mean you can't interact with smart contracts with the current version.
If you want to read from a smart contract you can just construct an instance of EthereumCall and then call eth.call(call:block:).
The return data will include the actual return value from the smart contract call.
Read the official contract abi specification to see how to construct the data
field of the EthereumCall
in order to read the smart contract values you want.
For calling actual state changing methods there is a similar procedure. You have to construct a normal EthereumTransaction just like you would if you wanted to send some ETH. Just set the value
to 0 (you don't want to send ETH, just call a method), set the to
to the smart contract address you want to call and add the input data into the data
parameter.
Then you have to sign this transaction with your private key as always (transaction.sign(with privateKey:)
) and call eth.sendRawTransaction(transaction:) just like you would for a normal transaction.
You will once again have to format the input data according to the contract abi specification I linked to above.
Like I said before, it's not quite easy yet but still possible, and in fact I have some working solutions.
If there is a high demand for ERC20 contract ABI calls I will post a gist with an example so you can copy & paste the hard part until the easy Contract ABI parser is finalized.
Hello @Ybrin!, this ethereum library has tremendous potential as it is tremendously easy to use and understand, and it's also semantically better than the rest of the libraries out there. I do hope however, that Contract interaction is finalized soon because that's a Core feature, or more like THE CORE feature any web3 implementation should enable. If possible I would really like to see the Example you're referring to.
Thank you for your detailed response.
@jlstr
Ok I made something which you can use for now specifically for ERC20 contracts.
Copy the following file into your project:
https://gist.github.com/Ybrin/c2db36fce19b821221b3f8fdb7bae7da
This adds an ERC20
struct into your project which has helper functions to create transactions for writing to and calls for reading from an ERC20 smart contract.
You can use it like that (Note: The examples below expect you to have installed the PromiseKit extensions and imported PromiseKit and Web3):
First of all initialize a new instance of ERC20 with the contract address
let erc20 = try ERC20(contractAddress: .init(hex: "0xb63b606ac810a52cca15e44bb630fd42d8d1d83d", eip55: false))
Also create your instance of Web3 with your JSON RPC URL
let infuraUrl = "https://mainnet.infura.io/<your_infura_id>"
let web3 = Web3(rpcURL: infuraUrl)
> Then you can start reading from the smart contract like that
```Swift
// *** Read ERC20 name
firstly {
web3.eth.call(call: erc20.reading.name(), block: .latest)
}.done { name in
// print the ERC20 name
print(String(bytes: Array(name.bytes.dropFirst(64))))
}.catch { error in
// Something went wrong
print(error)
}
// *** Read balance of an address
firstly {
try web3.eth.call(call: erc20.reading.balanceOf(owner: .init(hex: "0x00c09c3f03517ceb0a73eda1ff16e6c99f298175", eip55: false)), block: .latest)
}.done { balance in
// Print the balance of the above address
print(balance.hex())
}.catch { error in
// Something went wrong
print(error)
}
// All other reading functions work very similar...
If you want to call state changing functions like
transfer
orapprove
, you have to create the transaction and sign it. Below are some examples...
let privateKey = try EthereumPrivateKey(hexPrivateKey: "0xc144c24c9d75a46aad6517e4a864c13a5f302f1534b4bba39687e6d6af29d4fb")
firstly {
// Get the nonce
web3.eth.getTransactionCount(address: privateKey.address, block: .latest)
}.then { nonce in
// Create and sign transaction
return Promise { seal in
var transferTx = try erc20.writing.transfer(
nonce: nonce,
// Replace with whatever you want
gasPrice: EthereumQuantity(quantity: 21.gwei),
gasLimit: 150000,
// Replace with the address you are sending the tokens to
to: EthereumAddress(hex: "0xF92AB39A37CF96316132B50c8a85ED467A0deBE6", eip55: false),
// Replace with the number of tokens (in atomic units)
value: 100000,
// ChainId. 1 for mainnet. 3 for ropsten. 4 for rinkeby. 42 for kovan.
chainId: 1
)
// Sign with your private key
try transferTx.sign(with: privateKey)
seal.fulfill(transferTx)
}
}.then { tx in
// Send transaction to the Ethereum network
web3.eth.sendRawTransaction(transaction: tx)
}.done { hash in
// Print transactionHash. You can look this hash up and track the tx on https://etherscan.io once it was posted.
print(hash)
}.catch { error in
// Something went wrong
print(error)
}
The other writing functions should work similar. Just look through the struct ERC20.Writing
to see all possible options.
I hope I have covered everything for ERC20 tokens now.
If you have any questions or something doesn't work as expected just drop a comment.
You are right. General Contract ABI is actually our main priority right now as we also need it in our projects. Currently we are just tricking around like in the example above. This will definitely be done soon.
Hello, This is absolutely gorgeous. I haven't tested it yet, but it does look Magnificent! I will test it once I get a chance and let you know how it goes.
Always a pleasure to be able to be in contact with such talented individuals, can't thank you enough for this, Kindly, -Jose
Hi, Is it possible to sign transaction with keystore (generated by Geth) instead of private keys ?
@keithpiong You would have to extract the private key from the keystore. So you will need the passphrase and the keystore.
With both of them you can follow the instructions on how to extract the private key (with AES-128-CTR and scrypt) and then use this private key to create an instance of EthereumPrivateKey
to sign transactions like in the examples above.
If you want this private key extraction as a feature of Web3 please open a new issue. I think this is certainly something we will need at some point in time.
Thanks for the guide, I shall attempt to do so. Will also open a new issue on extracting private key from keystore.
I have contract deployed to Ropsten. The contract has functions with arguments. Not clear how to use Web3 to select the function in the contract. Any examples or tutorial available?
@blockcowboy Did you check out the examples for contract function calling in the README?
Yes. I had to change the eip55 to false to get around checksum error.
I see the try contract but can not identify the function selector.
Sorry
IJN
On Jul 6, 2018, at 10:34 AM, Koray Koska notifications@github.com wrote:
@blockcowboy Did you check out the examples for contract function calling in the README?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
I guess I need guide how to "create a static template"
Hello!
I have my own ERC20 contract, with transfer, transferFrom methods, etc. I would like to know how to get a reference to such a contract (via ABI + address combination?) and then make calls to its methods. Is this possible? If so, would you mind pointing out where can I find an example.
Thanks in advance, -Jose