Я пытаюсь создать DApp на Android с помощью Geth 1.5.9. После некоторых исследований и написания кода мне удалось найти информацию для установки/запуска узла geth, а также для создания некоторых учетных записей в Android Studio.
Я более или менее следовал инструкциям официальной Wiki и презентации Devcon2 — я знаю, что они не обновлены, но до сих пор мне этого было достаточно.
В любом случае, я хотел бы попробовать транзакцию сейчас, поэтому я попытался выполнить транзакцию с Account1 на Account2. Итак, я пошел в Ropsten-Faucet и получил немного эфира для обеих учетных записей, а затем попытался закодировать метод транзакции «sendTransaction», но у меня возникли некоторые проблемы с тем, чтобы сделать это правильно.
Как вы можете видеть в поле ниже, у меня есть ошибка, что отправитель транзакции не установлен правильно.
03-09 16:03:36.542 24705-24766/ch.zhaw.zendrio V/MainActivity: Start startSync
03-09 16:03:36.544 24705-24766/ch.zhaw.zendrio I/MainActivity: Start Transaction
03-09 16:03:36.545 24705-24766/ch.zhaw.zendrio I/MainActivity: Account1: 0xfa1c40e42d7317cd2a1b9cc88c9182e3c5efda5d
03-09 16:03:36.546 24705-24766/ch.zhaw.zendrio I/MainActivity: Account2: 0x8a9519da1f03e1fd5a558a6d43dc4ba06f1f955d
03-09 16:03:36.546 24705-24766/ch.zhaw.zendrio I/MainActivity: Nonce used:0
03-09 16:03:39.488 24705-24766/ch.zhaw.zendrio I/MainActivity: Cost: 2
03-09 16:03:39.488 24705-24766/ch.zhaw.zendrio I/MainActivity: GasPrice: 1
03-09 16:03:39.488 24705-24766/ch.zhaw.zendrio I/MainActivity: Gas: 1
03-09 16:03:39.488 24705-24766/ch.zhaw.zendrio I/MainActivity: Nonce: 0
03-09 16:03:39.490 24705-24766/ch.zhaw.zendrio I/MainActivity: Value: 1
03-09 16:03:39.490 24705-24766/ch.zhaw.zendrio I/MainActivity: Sig-Hash Hex: 0x300eb1c450fe26f71e13bdbf099b8a70f3015e069ef1fd9e0598e6c21c0b4224
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio I/MainActivity: Hash Hex: 0xdf050dcf9f8e2f508addab5a0359923b0a15689184732b84b7f10e3994ce6f1f
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio I/MainActivity: Data-Length: 11
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio I/MainActivity: To: 0x8a9519da1f03e1fd5a558a6d43dc4ba06f1f955d
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio V/MainActivity: invalid transaction v, r, s values
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err: go.Universe$proxyerror: invalid transaction v, r, s values
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err: at org.ethereum.geth.Transaction.getFrom(Native Method)
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err: at ch.zhaw.zendrio.view.activity.MainActivity.sendTransaction(MainActivity.java:136)
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err: at ch.zhaw.zendrio.view.activity.MainActivity.access$300(MainActivity.java:24)
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err: at ch.zhaw.zendrio.view.activity.MainActivity$2.run(MainActivity.java:88)
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err: at java.lang.Thread.run(Thread.java:761)
И вот где я застрял на несколько дней, и мне нужна помощь от вас, ребята.
Я использовал следующие тест-аккаунты и код ниже в полях:
Какие могут быть у меня проблемы:
private Node startNode() throws Exception {
final NodeConfig nodeConfig = new NodeConfig();
nodeConfig.setEthereumNetworkID(3); // Is this enough to connect to Ropsten??
Log.v(TAG, "Start Node");
Node node = Geth.newNode(getFilesDir() + "/.ethereum", nodeConfig);
node.start();
final NodeInfo nodeInfo = node.getNodeInfo();
runOnUiThread(new Runnable() {
@Override
public void run() {
// Show the config in the UI
final TextView textbox = (TextView) findViewById(R.id.GethTextbox);
textbox.append("My name: " + nodeInfo.getName() + "\n");
textbox.append("My address: " + nodeInfo.getListenerAddress() + "\n");
textbox.append("My protocols: " + nodeInfo.getProtocols() + "\n");
textbox.append("My ID: " + nodeInfo.getID() + "\n");
textbox.append("My ListenerPort: " + nodeInfo.getListenerPort() + "\n");
textbox.append("My IP: " + nodeInfo.getIP() + "\n\n");
textbox.append("NodeConfig: " + nodeConfig.toString() + "\n\n");
}
});
return node;
}
private void startSync(Node node) throws Exception {
//TODO Refactor/Delete
Log.v(TAG, "Start startSync");
ctx = new Context();
final TextView blockTextBox = (TextView) findViewById(R.id.blockTextBox);
ec = node.getEthereumClient();
//blockTextBox.append("Latest block: " + ec.getBlockByNumber(ctx, -1).getNumber() + ", syncing...\n");
NewHeadHandler handler = new NewHeadHandler() {
@Override
public void onError(String error) {
Log.e(TAG, error);
}
@Override
public void onNewHead(final Header header) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
blockTextBox.append("#" + header.getNumber() + ": " + header.getHash().getHex().substring(0, 10) + "…\n");
}
});
}
};
ec.subscribeNewHead(ctx, handler, 16);
}
private void sendTransaction() throws Exception {
Log.i(TAG,"Start Transaction");
KeyStore keyStore = new KeyStore(this.getFilesDir() + "/keystore",
Geth.StandardScryptN, Geth.StandardScryptP);
Accounts accounts = keyStore.getAccounts();
if(accounts.size() >= 2){
account1 = accounts.get(0);
account2 = accounts.get(1);
}
Log.i(TAG, "Account1: " + account1.getAddress().getHex()); //Sender
Log.i(TAG, "Account2: " + account2.getAddress().getHex()); //Receiver
BigInt value = Geth.newBigInt(1);
BigInt gasLimit = Geth.newBigInt(0);
BigInt gasPrice = Geth.newBigInt(0);
String testData = "Hello World";
byte[] data = testData.getBytes();
long nonce = ec.getPendingNonceAt(ctx, account1.getAddress()); // 1. Blocks the Thread if used? Syncing maybe?
//long nonce = 0x00;
Log.i(TAG, "Nonce used:" + nonce);
Transaction transaction = Geth.newTransaction(nonce, account2.getAddress(), value, gasLimit, gasPrice, data);
keyStore.timedUnlock(account1, "test", 10000000);
transaction = keyStore.signTx(account1, transaction, new BigInt(0)); // 2. Why BigInt needed?
Log.i(TAG, "Cost: " + transaction.getCost());
Log.i(TAG, "GasPrice: " + transaction.getGasPrice());
Log.i(TAG, "Gas: " + transaction.getGas());
Log.i(TAG, "Nonce: " + transaction.getNonce());
Log.i(TAG, "Value: " + transaction.getValue());
Log.i(TAG, "Sig-Hash Hex: " + transaction.getSigHash().getHex());
Log.i(TAG, "Hash Hex: " + transaction.getHash().getHex());
Log.i(TAG, "Data-Length: " + transaction.getData().length);
Log.i(TAG, "To: " + transaction.getTo().getHex());
Log.i(TAG, "Sender: " + transaction.getFrom().getHex()); // 3. Produces the Error-Output.
ec.sendTransaction(ctx, transaction);
}
Извините за длинный пост и спасибо за помощь!
Я не уверен, но потенциально есть три проблемы:
Вам понадобится доступ к блоку генезиса Ropsten для правильной синхронизации, хотя я думаю, что geth каким-то образом сможет сделать это за вас. (Это происходит на ПК.) Тем не менее, Ropsten сейчас более или менее сломан из-за атак. Вам больше повезет, если вы создадите частную цепочку, как описано здесь .
Этот одноразовый номер должен точно совпадать с текущим одноразовым номером учетной записи, иначе его нельзя будет майнить. Если учетные записи новые, это значение обычно равно нулю. Однако я считаю, что одноразовые номера тестовой сети начинаются с другого числа, чтобы избежать повторных атак. (Частные тестовые сети работают как обычно.)
Я предполагаю, что BigInt, вероятно, должно быть 3 из-за этого раздела в коде geth. Я предполагаю, что это связано с предотвращением повторных атак .
Наконец (я думаю, вы столкнетесь с этим позже), ваш газ и цена газа слишком низки. газ должен быть не менее 2300 (IIRC), чтобы даже выполнить транзакцию. gasPrice обычно составляет около 20 Gwei, и я предполагаю, что он запрашивает цену в wei.
Том
Том
Том
Мэтью Шмидт