Boilertalk / Web3.swift

A pure swift Ethereum Web3 library
MIT License
639 stars 188 forks source link

How to send signed raw transaction with some data? #69

Open tzuhanli opened 6 years ago

tzuhanli commented 6 years ago

Hello, I have a simple smart contract about read and write some value.

I can read my “owner” value successfully, but can not write value to the “owner”. When I send transaction to contract, it will return “*Error(code: -32000, message: “insufficient funds for gas price + value”)”, but I’m sure my account have enough gas. (2996400390000000001**)

I created a EthereumTransaction, signed it with my privateKey, and use “sendRawTransaction” to send it. Please help me realize my problem, thank you very much!

My Contract:

pragma solidity ^0.4.4;

contract Car {
  bytes public vehicleName = "Tesla";
  uint public owner;

  function setOwner(uint newOwner) public
  {
    owner = newOwner;
  }
}

My Code:


////////////////////////////
/// owner
do {
    let contract = try web3.eth.Contract(json: data!, abiKey: "abi", address: contractAddress)
            firstly {
                contract["owner"]!().call()
                }.done { outputs in
                    print(outputs)
                }.catch { error in
                    print(error)
            }
} catch {
    print(error)
}

////////////////////////////
/// setOwner
do {
    let myPrivateKey = try EthereumPrivateKey(hexPrivateKey: "**********")

    web3.eth.getBalance(address: myPrivateKey.address, block: try .string("latest") ) { response in
        print("myAccount - result?.quantity(wei): ", response.result?.quantity)
    }

    let contract: DynamicContract = try web3.eth.Contract(json: data!, abiKey: "abi", address: contractAddress)

    let c = contract["setOwner"]?(contractAddress!,BigUInt(789))
    let transaction: EthereumTransaction = c!
        .createTransaction(nonce: 0,
                            from: myPrivateKey.address,
                           value: 0,
                             gas: 210000,
            gasPrice: EthereumQuantity(quantity: 1.gwei))!

    let signedTx: EthereumSignedTransaction = try transaction.sign(with: myPrivateKey)

    firstly {
        web3.eth.sendRawTransaction(transaction: signedTx)
    }.done { txHash in
        print(txHash)
    }.catch { error in
        print(error)
    }

} catch {
    print(error)
}
koraykoska commented 6 years ago

Please change the following line:

let signedTx: EthereumSignedTransaction = try transaction.sign(with: myPrivateKey)

to something like that:

let signedTx: EthereumSignedTransaction = try transaction.sign(with: myPrivateKey, chainId: 1)

and change the chainId accordingly if you are in a different network than mainnet. See this link for testnet chainIds.

62 Will "solve" this issue by removing the default value of 0. Actually you should never omit the chainId to have the simple replay protection from EIP155.