RPC节点参与网络的同步,主要用于查询区块链数据,广播交易等作用;不会参与共识,挖矿。
有一定的linux基础
熟悉docker
linux系统
机器上有docker服务
Dockerfile
FROM 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
常用方法:
getblockchaininfo 获取最新区块
getblockhash 获取区块高度hash值
getblock 获取区块详情
getrawtransaction 获取交易详情
参考文档: BTC官方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 此字段为当前区块高度
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的地址都是使用椭圆曲线算法生成,支持离线生成。
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)