Go-Ethereum
TransactionException:在 web3j 中部署契約時無法解組無效的十六進製字元串
我有一個 java 伺服器,它使用 web3j 庫和 geth 作為提供者。當我試圖在我的私人測試網上部署我的契約時。我收到了這個錯誤:
org.web3j.protocol.exceptions.TransactionException: Transaction 0x70fed47c9d291f0818ff239be085b2dc3a87f436f56b9c0b6750e568a24dbdf1 has failed with status: 0x0. Gas used: 6721975. Revert reason: 'invalid argument 0: json: cannot unmarshal invalid hex string into Go struct field CallArgs.data of type hexutil.Bytes'. at org.web3j.tx.Contract.executeTransaction(Contract.java:377) at org.web3j.tx.Contract.create(Contract.java:422) at org.web3j.tx.Contract.deploy(Contract.java:456) at org.web3j.tx.Contract.deploy(Contract.java:506) at org.web3j.tx.Contract.lambda$deployRemoteCall$5(Contract.java:549) at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:42) at java_ethereum.ContractController.deployContract(ContractController.java:41)
我的 java 程式碼看起來像這樣:
Web3j web3 = Web3j.build(new HttpService("http://localhost:8545")); Credentials credentials = WalletUtils.loadCredentials("", "path/to/geth/keystore"); String contractAddress = deployContract(web3, credentials); MyContract myContract = loadContract(contractAddress, web3, credentials); @SuppressWarnings("deprecation") private String deployContract(Web3j web3, Credentials credentials) throws Exception{ return myContract.deploy(web3, credentials, GAS_PRICE, GAS_LIMIT).send().getContractAddress(); }
我的 web3j 應該是最新版本(4.8.4),我不確定我是否遺漏了什麼。契約的內容應該無關緊要(我認為),因為即使我嘗試部署空白契約也會彈出相同的錯誤。我懷疑從 geth 創建的憑據存在一些問題。任何幫助,將不勝感激。
我的初始化 geth 節點的命令:
geth --identity "TestNode" --rpc -rpcaddr "0.0.0.0" --rpcport "8545" --port "30303" --nodiscover --rpcapi "db,eth,net,web3,miner,net,personal,net,txpool,debug,admin" --networkid 1900 --datadir C:/Users/Documents/Test --allow-insecure-unlock --ipcdisable --dev --dev.period 1
@Majd TL 建議改為在 ganache 上測試它,這次它返回不同的錯誤:
java.lang.RuntimeException: java.lang.RuntimeException: Error processing transaction request: VM Exception while processing transaction: invalid opcode at org.web3j.tx.Contract.deploy(Contract.java:460) at org.web3j.tx.Contract.deploy(Contract.java:506) at org.web3j.tx.Contract.lambda$deployRemoteCall$5(Contract.java:549) at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:42) at ContractController.deployContract(ContractController.java:52) Caused by: java.lang.RuntimeException: Error processing transaction request: VM Exception while processing transaction: invalid opcode at org.web3j.tx.TransactionManager.processResponse(TransactionManager.java:162) at org.web3j.tx.TransactionManager.executeTransaction(TransactionManager.java:81) at org.web3j.tx.ManagedTransaction.send(ManagedTransaction.java:127) at org.web3j.tx.Contract.executeTransaction(Contract.java:367) at org.web3j.tx.Contract.create(Contract.java:422) at org.web3j.tx.Contract.deploy(Contract.java:456) ... 11 more
好的,我知道發生了什麼。
參考這篇文章Web3j gets stack underflow error with Ganache,事實證明 Web3j CLI 不接受和正確處理從 Remix-IDE 生成的任何二進製文件(不知道為什麼,但肯定是一個錯誤)。
所以我將 IDE 切換到 Buidl 進行編譯,現在它在 ganache 和 geth 上都能完美執行。
作為另一種方式。如果您有智能合約,您實際上可以使用web3j-gradle-plugin 隨時隨地編譯合約並部署它(無需手動複製生成的 java 包裝器)。
為此,只需使用以下命令將外掛應用到您的項目中:
plugins { id "org.web3j" version "4.8.4" }
如果您使用的是gradle。如果沒有,您也可以為 Maven 項目指定它。
然後,將智能合約放在
src/main/solidity
文件夾下,它會被自動拾取、編譯並生成 java 包裝器,也可以直接從您的程式碼中使用。