#java #sockets #networking #protocols #bitcoin
#java #сокеты #сеть #протоколы #биткойн
Вопрос:
Я разрабатываю протокол биткойн с использованием сокета, но столкнулся с некоторыми проблемами. Во-первых, когда мой код подключается к узлу биткойн, он не дает никакого ответа. Я отправляю сообщение о версии, но другой боковой узел ничего не отправляет повторно. Я думаю, что проблема может заключаться в том, что я неправильно реализую протокол, но я проверил и думаю, что все в порядке. (2) Во-вторых, я думаю, что может быть невозможно подключиться к узлу биткойн с использованием сокета, но это глупая идея. Да?
Одна важная вещь, я закодировал только соединение с сокетом, отправив версию на биткойн-узел, который я нашел наhttps://bitnodes.earn.com/nodes / и получение сообщения от узла, но он всегда отвечает -1. Еще одна вещь, я не даю ответа от узла, но также не выдаю ошибку подключения. (Я просто говорю)
Пожалуйста, помогите мне 🙂
Что плохого в том, что я отправляю сообщение о версии, но затем не выдает другое от узла?
Кроме того, я прикрепляю выходные данные (фазы подключения и структуру протокола) консоли при попытке подключиться к сокету.
Connected
f9beb4d976657273696f6e0000000000000000660a75c8397f1101000100000000000000820b905c00000000010000000000000000000000000000000000ffff340e5966208d010000000000000000000000000000000000ffff7f000001208db910e81a17a5dd79102f417572696d61733a302e31362e332f0000000001
Magic:f9beb4d9
Command:76657273696f6e0000000000
Length:00000066
Checksum:0a75c839
Payload:7f1101000100000000000000820b905c00000000010000000000000000000000000000000000ffff340e5966208d010000000000000000000000000000000000ffff7f000001208db910e81a17a5dd79102f417572696d61733a302e31362e332f0000000001
Version:7f110100
Services:0100000000000000
timestamp:820b905c00000000
addr_recv:010000000000000000000000000000000000ffff340e5966208d
addr_from:010000000000000000000000000000000000ffff7f000001208d
nonce:b910e81a17a5dd79
user_agent:102f417572696d61733a302e31362e332f
start_height:00000000
relay:01
Connection end
Основной класс:
private static String address = "52.14.89.102";
private static int port = 8333;
public static void main(String [] args) throws IOException {
String line = "";
try {
socket = new Socket(address, port);
System.out.println("Connected");
input = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
VersionMessage message = new VersionMessage();
line = Hex.encodeHexString(message.getMessage());
System.out.println(line);
structure(message.getMessage());
out.writeBytes(line);;
} catch(UnknownHostException u) {
System.out.println(u);
} catch (IOException e) {
e.printStackTrace();
}
...
Часть класса VersionMessage:
public VersionMessage() {
super();
this.version = 70015;
this.services = 1; // NODE_NETWORK
this.timestamp = System.currentTimeMillis() / 1000;
this.nonce = new Random().nextLong();
this.userAgent = "/Satoshi:0.16.3/";
this.startHeight = 0;
this.relay = true;
contructPayload();
contructMessage();
}
@Override
public void contructPayload() {
addByteArray(dataParser.toInt32(version));
addByteArray(dataParser.toInt64(services));
addByteArray(dataParser.toInt64(timestamp));
addAddr("52.14.89.102", 8333);
addAddr("127.0.0.1", 8333);
addByteArray(dataParser.toInt64(nonce));
addStr(userAgent);
addByteArray(dataParser.toInt32(startHeight));
addByteArray(dataParser.toInt8(relay ? (byte) 1 : (byte) 0));
payload = new byte[payloadBytes.size()];
IntStream.range(0, payloadBytes.size()).forEach(i -> payload[i] = payloadBytes.get(i).byteValue());
}
BitcoinMessage (родительский элемент VersionMessage):
public BitcoinMessage() {
magic = 0xf9beb4d9;;
payloadBytes = new ArrayList<Integer>();
dataParser = new DataParser();
}
public void contructMessage() {
message = new byte[MAGIC_LENGTH COMMAND_LENGTH PAYLOAD_LENGTH_SIZE CHECKSUM_LENGTH payload.length];
length = payload.length;
byte[] doubleHashedPayload = MessageUtils.doubleHashWithSha256(payload);
MessageUtils.addToByteArray(MessageUtils.intToBytes(magic, MAGIC_LENGTH), 0, MAGIC_LENGTH, message);
MessageUtils.addToByteArray(getCommandName().getBytes(), MAGIC_LENGTH, COMMAND_LENGTH, message);
MessageUtils.addToByteArray(MessageUtils.intToBytes(length, PAYLOAD_LENGTH_SIZE), MAGIC_LENGTH COMMAND_LENGTH, PAYLOAD_LENGTH_SIZE, message);
MessageUtils.addToByteArray(doubleHashedPayload, MAGIC_LENGTH COMMAND_LENGTH PAYLOAD_LENGTH_SIZE, CHECKSUM_LENGTH, message);
MessageUtils.addToByteArray(payload, MAGIC_LENGTH COMMAND_LENGTH PAYLOAD_LENGTH_SIZE CHECKSUM_LENGTH, payload.length, message);
}
Комментарии:
1. Сложно проверить свой код, не запустив его в режиме отладки шаг за шагом. Я сам написал класс на C #, который может это сделать. Если у вас есть возможность отлаживать код C #, вы можете сравнить 2 реализации.
2. Я добавляю проект: github.com/nastae/bitcoin-protocol