我有一份可以编译的合同,并且功能已经过测试。我在 testrpc 上部署它(使用 web3j)但是我收到了一个invalid opcode
错误。
我认为它不像 testrpc 输出那么重要Contract created
Transaction: 0xee46dd1227638b29dc1e9675b84bace7c38ae8c77b6b36e730e3475dde25da9e
Contract created: 0xc09fc91f653dac6a22c940edec4786f2ac7885c6
Gas usage: 0x47e7c4
Block Number: 0x03
Block Time: Fri Jun 16 2017 13:39:45 GMT+0200 (CEST)
Runtime Error: invalid opcode
加载合同没有输出任何异常,但是我无法使用任何功能。谁能帮我理解发生了什么?合同实际上是在 testrpc 上吗?我会对你能给我的任何信息感兴趣。
public void deployStreak() {
try {
contract = Streak.deploy(web3j, credentials, GAS_PRICE, GAS_LIMIT, INITIAL_WEI).get();
} catch (Exception e) {
e.printStackTrace();
}
}
编辑:使用 web3j 的包装器(自动生成)包装合同。我与包装器交互的实现如下(略微简化)。
public class EthereumApi {
private static final String INFURA_MAIN_NODE = "https://mainnet.infura.io/xxx";
private static final String INFURA_TEST_NODE = "https://ropsten.infura.io/xxx";
private static final BigInteger GAS_PRICE = new BigInteger("100000000000");
private static final BigInteger GAS_LIMIT = new BigInteger("4712388");
private static final BigInteger INITIAL_WEI = new BigInteger("1");
private static final String PRIVATE_KEY = "a60931fc499e82b283b4406bef947e6d74d3a3ff3de6a51e3da4aacc17286723";
private static final boolean DEV_MODE = true;
private static EthereumApi instance = null;
private Web3j web3j;
private Streak contract = null;
private String contractAddress = "0x5879b9d58fd0e033c3114c5ab1d4228485708537";
private Credentials credentials;
private EthereumApi() {
if(DEV_MODE) {
web3j = Web3j.build(new HttpService());
System.out.println("[ETH-INFO] Connected to TestRPC");
} else {
web3j = Web3j.build(new InfuraHttpService(INFURA_TEST_NODE));
System.out.println("[ETH-INFO] Connected to Infura Node on Ropsten...");
}
credentials = Credentials.create(PRIVATE_KEY);
System.out.println("Credentials: " + credentials.getAddress());
}
/**
* Singleton to access the API instance
*/
public static EthereumApi getInstance() {
if(instance == null) {
instance = new EthereumApi();
}
return instance;
}
/**
* Delete instance of the API
*/
public void close() {
instance = null;
}
public String getClientVersion() {
String version = null;
try {
version = web3j.web3ClientVersion().sendAsync().get().getWeb3ClientVersion();
} catch (Exception e) {
e.printStackTrace();
this.close();
}
return version;
}
/**
* Sends `amount` ether from the main account to `address`
*/
public void sendEth(String address, Long amount) {
try {
TransactionReceipt receipt = Transfer.sendFunds(
web3j, credentials, address, BigDecimal.valueOf(amount), Convert.Unit.ETHER);
} catch (Exception e) {
e.printStackTrace();
this.close();
}
}
public void deployStreak() {
try {
contract = Streak.deploy(web3j, credentials, GAS_PRICE, GAS_LIMIT, INITIAL_WEI).get();
} catch (Exception e) {
e.printStackTrace();
}
}
public void loadStreak() {
try {
contract = Streak.load(contractAddress, web3j, credentials, GAS_PRICE, GAS_LIMIT);
} catch (Exception e) {
e.printStackTrace();
}
}
public void loadStreak(String address) {
try {
contract = Streak.load(address, web3j, credentials, GAS_PRICE, GAS_LIMIT);
} catch (Exception e) {
e.printStackTrace();
}
}
}