# BTC RPC节点部署 **Published by:** [junjie9021.eth](https://paragraph.com/@junjie9021/) **Published on:** 2022-10-22 **URL:** https://paragraph.com/@junjie9021/btc-rpc ## Content RPC节点参与网络的同步,主要用于查询区块链数据,广播交易等作用;不会参与共识,挖矿。阅读者建议有一定的linux基础熟悉docker安装前置条件linux系统机器上有docker服务部署脚本DockerfileFROM ubuntu:20.04 ARG VERSION=22.0 RUN apt-get update \ && apt-get install -y net-tools curl \ && curl -o /tmp/bitcoin.tar.gz https://bitcoincore.org/bin/bitcoin-core-${VERSION}/bitcoin-${VERSION}-x86_64-linux-gnu.tar.gz \ && tar -zxvf /tmp/bitcoin.tar.gz -C /opt \ && mv /opt/bitcoin-* /opt/bitcoin \ && ln -s /opt/bitcoin/bin/* /usr/local/bin \ && rm -f /tmp/bitcoin.tar.gz WORKDIR /btc EXPOSE 8332 ENTRYPOINT ["sh", "-c", "bitcoind -datadir=/btc -rpcbind=0.0.0.0 -rpcallowip=0.0.0.0/0 -txindex -rpcworkqueue=1000 -rpcuser=$RPC_USER -rpcpassword=$RPC_PWD"] run.sh 脚本#!/bin/bash # 如果需要升级版本,修改这里的版本号后,执行一下run.sh脚本即可。 VERSION=22.0 docker build --build-arg VERSION=$VERSION -t btc:$VERSION . docker stop btc docker rm btc docker run -d --name btc -p 8332:8332 -v /data/btc:/btc -e RPC_USER="test" -e RPC_PWD="test" --restart=always btc:$VERSION 对run.sh赋予执行权限,运行脚本 查看日志docker logs -f --tail 20 btc 节点日志,经过一段时间,追赶上最新区块RPC接口常用方法:getblockchaininfo 获取最新区块getblockhash 获取区块高度hash值getblock 获取区块详情getrawtransaction 获取交易详情参考文档: BTC官方RPC接口 https://developer.bitcoin.org/reference/rpc/获取最新区块高度curl -X POST -u test:test -d '{"jsonrpc": "2.0", "method": "getblockchaininfo", "params": [], "id": 1}' http://localhost:8332 { "result": { "chain": "main", "blocks": 759822, "headers": 759822, "bestblockhash": "0000000000000000000096b2e9a0db174eeb7a4c15e8a38398593f36032cfb09", "difficulty": 35610794164371.65, "time": 1666441676, "mediantime": 1666438889, "verificationprogress": 0.9999988460882687, "initialblockdownload": false, "chainwork": "000000000000000000000000000000000000000037b5d76943db7b147d7b83e6", "size_on_disk": 492851010520, "pruned": false, "warnings": "" }, "error": null, "id": 1 } # "blocks": 759822 此字段为当前区块高度 获取区块高度的hash值curl -X POST -u test:test -d '{"jsonrpc": "2.0", "method": "getblockhash", "params": [759822], "id": 1}' http://localhost:8332 { "result": "0000000000000000000096b2e9a0db174eeb7a4c15e8a38398593f36032cfb09", "error": null, "id": 1 } … 其余接口建议大家自己去尝试题外话安全: RPC节点主要会被Wallet, Dapp, Cex等应用使用。自建RPC节点使用起来也会更安全,放心,不用担心你的请求会被他人拦截导致私密信息的泄漏。 地址: 类BTC,ETH的地址都是使用椭圆曲线算法生成,支持离线生成。离线生成地址Python代码样例import ecdsa import base58 import hashlib import binascii class Wallet: def __init__(self, network='mainnet'): # 版本前缀 self.__pubkey_version_byte = '00' if network == 'mainnet' else '6F' self.__wif_version_byte = '80' if network == 'mainnet' else 'ef' @property def pubkey_version_byte(self): return self.__pubkey_version_byte @pubkey_version_byte.setter def pubkey_version_byte(self, v): if isinstance(v, str): raise ValueError self.__pubkey_version_byte = v @property def wif_version_byte(self): return self.__wif_version_byte @wif_version_byte.setter def wif_version_byte(self, v): if isinstance(v, str): raise ValueError self.__wif_version_byte = v def __generate_privkey(self): privkey = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) return privkey def get_pubkey(self, compress=False, privkey=None): if not privkey: privkey = self.__generate_privkey() # 是否压缩,压缩格式的公钥前缀是0x02或0x03,不压缩格式的公钥前缀是0x04 s = '02' if compress else '04' pubkey = s + privkey.get_verifying_key().to_string().hex() return pubkey def get_address(self, pubkey): """根据公钥获取地址""" # 1.处理传入公钥格式 sha256Key = hashlib.sha256(binascii.unhexlify(pubkey)).hexdigest() ridemp160FromHash256 = hashlib.new('ripemd160', binascii.unhexlify(pubkey)) # 2.将 00 作为网络字节添加ripemd160公钥 prepend_network_byte = self.__pubkey_version_byte + ridemp160FromHash256.hexdigest() # 3.将双重 SHA256 应用于prepend_network_byte以校验和 hash = prepend_network_byte for x in range(1,3): hash = hashlib.sha256(binascii.unhexlify(hash)).hexdigest() checksum = hash[:8] # 4.附加值 append_checksum = prepend_network_byte + checksum # 5.base58编码 address = base58.b58encode(binascii.unhexlify(append_checksum)) return address.decode('utf8') def generate(self): """生成地址""" privkey = self.__generate_privkey() pubkey = self.get_pubkey(privkey) address = self.get_address(pubkey) self.privkey = privkey.to_string().hex() self.pubkey = pubkey self.address = address return address def privkey_to_wif(self, privkey): """私钥格式转钱包导入格式""" prepend_network_byte = self.__wif_version_byte + privkey hash = prepend_network_byte for x in range(1,3): hash = hashlib.sha256(binascii.unhexlify(hash)).hexdigest() checksum = hash[:8] append_checksum = prepend_network_byte + checksum privkey = base58.b58encode(binascii.unhexlify(append_checksum)) return privkey.decode('utf8') if __name__ == '__main__': wallet = Wallet() wallet.generate() print(wallet.address, wallet.privkey) ## Publication Information - [junjie9021.eth](https://paragraph.com/@junjie9021/): Publication homepage - [All Posts](https://paragraph.com/@junjie9021/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@junjie9021): Subscribe to updates - [Twitter](https://twitter.com/shiwuzhe): Follow on Twitter