编写python脚本调用ordinals以及BRC20的接口

news2025/1/15 13:53:54

初始版本

#!/usr/bin/python3

from flask import Flask, request, jsonify
import subprocess
import json
import os

app = Flask(__name__)

ord_cmd = ["/root/ord/target/release/ord", "--cookie-file=/data/btcregtest/data/regtest/.cookie", "--rpc-url=127.0.0.1:8540", "-r"]

bitcoin_cli_cmd=["/data/btcregtest/bin/bitcoin-cli", "-regtest", "--conf=/data/btcregtest/conf/bitcoin-regtest.conf", "-rpcwallet=btcregtest"]


@app.route('/walletreceive', methods=['POST'])
def wallet_receive():
    try:
        num = int(request.json['num'])
        return wallet_receive_impl(num)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/inscription', methods=['POST'])
def inscription():
    try:
        fee_rate = request.json['fee_rate']
        tick = request.json['tick']
        amount = request.json['amount']
        destination = request.json['destination']
        return inscription_impl(fee_rate, tick, amount, destination)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/send', methods=['POST'])
def send():
    try:
        fee_rate = request.json['fee_rate']
        address = request.json['address']
        inscription_id = request.json['inscription_id']
        return send_impl(fee_rate, address, inscription_id)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/sendtoaddress', methods=['POST'])
def sendtoaddress():
    try:
        address = request.json['address']
        count = request.json['count']
        return sendtoaddress_impl(address, count)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/generate', methods=['POST'])
def generate():
    try:
        count = request.json['count']
        return generate_impl(count)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/getrawtransaction', methods=['POST'])
def getrawtransaction():
    try:
        hash_id = request.json['hash_id']
        return getrawtransaction_impl(hash_id)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/wallet_balance', methods=['POST'])
def wallet_balance():
    try:
        return wallet_balance_impl()
    except Exception as e:
        return jsonify({"error": str(e)}), 400
                
@app.route('/wallet', methods=['POST'])
def wallet():
    try:
        wallet_method = request.json['wallet_method']
        return wallet_impl(wallet_method)
    except Exception as e:
        return jsonify({"error": str(e)}), 400


def wallet_receive_impl(num):
    addresses = []
    for i in range(1, num + 1):
        command = ord_cmd + ["wallet", "receive"]
        output = subprocess.check_output(command)
        address = json.loads(output.decode().strip().replace("'", "\""))["address"]
        addresses.append(address)

    return addresses


def inscription_impl(fee_rate, tick, amount, destination):
    fee_rate_file = "/root/fee_rate_file.json"

    with open(fee_rate_file, "w") as json_file:
        json.dump({"p": "brc-20", "op": "transfer", "tick": tick, "amount": str(amount)}, json_file)

    command = ord_cmd + ["wallet", "inscribe", "--fee-rate", str(fee_rate), "--file", fee_rate_file, "--destination", destination]
    result = subprocess.check_output(command)
    return result.decode().strip()

def send_impl(fee_rate, address, inscription_id):                
    command = ord_cmd + ["wallet", "send", "--fee-rate", str(fee_rate), address, inscription_id]
    result = subprocess.check_output(command)
    return result.decode().strip()

def sendtoaddress_impl(address, count):               
    command = bitcoin_cli_cmd + ["sendtoaddress", address, str(count)]
    result = subprocess.check_output(command)
    return result.decode().strip()

def generate_impl(count):    
    command = bitcoin_cli_cmd + ["-generate", count]
    result = subprocess.check_output(command)
    return result.decode().strip()

def getrawtransaction_impl(hash_id):    
    command = bitcoincli_cmd + ["getrawtransaction", hash_id, "true"]
    result = subprocess.check_output(command)
    return result.decode().strip()

def wallet_balance_impl():
    command = ord_cmd + ["wallet", "balance"]
    result = subprocess.check_output(command)
    return result.decode().strip()    

def wallet_impl(wallet_method):
    command = ord_cmd + ["wallet", wallet_method]
    
    # 使用 subprocess.run 获取命令执行结果和错误输出
    result = subprocess.run(command, capture_output=True, text=True)
    return run_command(command)

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=5000)

优化后,正常返回节点的错误信息

#!/usr/bin/python3

from flask import Flask, request, jsonify,make_response
import subprocess
import json
import os
import re 
import logging 

app = Flask(__name__)

ord_cmd = ["/data/ord/target/release/ord", "--cookie-file=/data/btc/btcdata/regtest/.cookie", "--rpc-url=127.0.0.1:8540", "-r"]

bitcoin_cli_cmd=["/data/btc/bin/bin/bitcoin-cli", "-regtest", "--conf=/data/btc/conf/bitcoin.conf", "-rpcwallet=btcregtest"]
bitcoincli_cmd=["/data/btc/bin/bin/bitcoin-cli", "-regtest", "--conf=/data/btc/conf/bitcoin.conf"]

def run_command(command):
    try:
        # 使用 subprocess.run 获取命令执行结果和错误输出
        result = subprocess.run(command, capture_output=True, text=True)

        # 如果命令返回非零退出码,表示发生错误
        if result.returncode != 0:
            # 从错误输出中提取包含 "error" 的部分
            match = re.search(r'error:.*', result.stderr, re.IGNORECASE)
            processed_error_message = match.group(0) if match else "Unknown error"

            # 记录错误到日志
            logging.error("Error in command execution: %s", result.stderr)

            # 手动创建 JSON 响应并设置状态码
            response = jsonify({"error": processed_error_message, "normal_output": result.stdout.strip()})
            response.status_code = 500
            return response

        # 记录正常输出到日志
        logging.info("Normal output in command execution: %s", result.stdout)

        # 返回正常输出到客户端
        return result.stdout.strip()

    except Exception as e:
        # 记录异常到日志
        logging.error("Error in command execution: %s", str(e))
        return str(e), 500

@app.route('/walletreceive', methods=['POST'])
def wallet_receive():
    try:
        num = int(request.json['num'])
        return wallet_receive_impl(num)
    except Exception as e:
        return str(e), 400

@app.route('/inscription', methods=['POST'])
def inscription():
    try:
        fee_rate = request.json['fee_rate']
        tick = request.json['tick']
        amount = request.json['amount']
        destination = request.json['destination']
        return inscription_impl(fee_rate, tick, amount, destination)
    except Exception as e:
        return jsonify({"error": str(e)}), 400


@app.route('/send', methods=['POST'])
def send():
    try:
        fee_rate = request.json['fee_rate']
        address = request.json['address']
        inscription_id = request.json['inscription_id']
        return send_impl(fee_rate, address, inscription_id)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/sendtoaddress', methods=['POST'])
def sendtoaddress():
    try:
        address = request.json['address']
        count = request.json['count']
        return sendtoaddress_impl(address, count)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/generate', methods=['POST'])
def generate():
    try:
        count = request.json['count']
        return generate_impl(count)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/getrawtransaction', methods=['POST'])
def getrawtransaction():
    try:
        hash_id = request.json['hash_id']
        return getrawtransaction_impl(hash_id)
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/wallet', methods=['POST'])
def wallet():
    try:
        wallet_method = request.json['wallet_method']
        return wallet_impl(wallet_method)
    except Exception as e:
        return jsonify({"error": str(e)}), 400


def wallet_receive_impl(num):
    addresses = []
    for i in range(1, num + 1):
        command = ord_cmd + ["wallet", "receive"]
        output = subprocess.check_output(command)
        address = json.loads(output.decode().strip().replace("'", "\""))["address"]
        addresses.append(address)

    return addresses


def inscription_impl(fee_rate, tick, amount, destination):
    fee_rate_file = "/root/fee_rate_file.json"

    with open(fee_rate_file, "w") as json_file:
        json.dump({"p": "brc-20", "op": "transfer", "tick": tick, "amount": str(amount)}, json_file)

    command = ord_cmd + ["wallet", "inscribe", "--fee-rate", str(fee_rate), "--file", fee_rate_file, "--destination", destination]
    return run_command(command)

def send_impl(fee_rate, address, inscription_id):
                
    command = ord_cmd + ["wallet", "send", "--fee-rate", str(fee_rate), address, inscription_id]

    # 使用 subprocess.run 获取命令执行结果和错误输出
    result = subprocess.run(command, capture_output=True, text=True)
    return run_command(command)

def sendtoaddress_impl(address, count):
                
    command = bitcoin_cli_cmd + ["sendtoaddress", address, str(count)]
    return run_command(command)

def generate_impl(count):
    
    command = bitcoin_cli_cmd + ["-generate", count]

    # 使用 subprocess.run 获取命令执行结果和错误输出
    result = subprocess.run(command, capture_output=True, text=True)
    return run_command(command)

def getrawtransaction_impl(hash_id):
    
    command = bitcoincli_cmd + ["getrawtransaction", hash_id, "true"]

    # 使用 subprocess.run 获取命令执行结果和错误输出
    result = subprocess.run(command, capture_output=True, text=True)
    return run_command(command)

def wallet_impl(wallet_method):
    
    command = ord_cmd + ["wallet", wallet_method]

    # 使用 subprocess.run 获取命令执行结果和错误输出
    result = subprocess.run(command, capture_output=True, text=True)
    return run_command(command)

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=5000)

测试验证
所有接口都是post请求,采用postman进行测试
1、钱包地址生成walletreceive,对应ord命令:ord wallet receive
测试地址:http://192.168.25.128:5000/walletreceive
测试参数:
其中数值代表要新生成的地址数

{"num": "1"}

测试结果示例
在这里插入图片描述
2、钱包币种铭刻inscription,
对应ord命令

ord --cookie-file btcdata/.cookie -r wallet inscribe --fee-rate 50 --file fee.json

fee.json文本模板

{"p":"brc-20","op":"transfer","tick":"ordi","amt":"10"}

测试结果
测试地址:http://192.168.25.128:5000/inscription
测试参数

{"fee_rate": "37", 
"tick": "ordi", 
"amount": "0.25564588", 
"destination": "bcrt1pp76laj6axjryppcfw2vjuyhpq75ndulkcmm3dq59le52qlfmdpws26zrpd"
}

在这里插入图片描述
3、铭文转账send
对应ord命令

ord --cookie-file btcdata/.cookie -r wallet send --fee-rate 50 钱包地址 铭文id

测试地址:http://192.168.25.128:5000/send
测试参数:

{
"fee_rate": "40", 
"address": "bcrt1pp76laj6axjryppcfw2vjuyhpq75ndulkcmm3dq59le52qlfmdpws26zrpd", "inscription_id": "1757702fcffbea626de0f524b76f048f87e43351640b92d6eddbcc93e68c44e9i0"
}

测试结果:
在这里插入图片描述
4、测试bitcoin转币sendtoaddress
对应bitcoin-cli命令

./btcoin-cli -rpcwallet=btcregtest(钱包名称)  sendtoaddress bcrt1pprdrceqpc2sy8fr60jqaaatkw5wne2j3g0xljtn0wskajwafgc8qxac384(目的钱包地址) 10(币种数量)

测试地址:http://192.168.25.128:5000/sendtoaddress
测试参数:

{"address": "bcrt1pp76laj6axjryppcfw2vjuyhpq75ndulkcmm3dq59le52qlfmdpws26zrpd", 
"count": "10"}

测试结果
在这里插入图片描述

5、测试通过hash查询交易getrawtransaction
对应bitcoin-cli命令

./btcoin-cli getrawtransaction hash_id true

测试地址:http://192.168.25.128:5000/getrawtransaction
测试参数:

{"hash_id": "731237ec34e833713d349daf30f1e66d69a31ca261af84ea787368d017ef9f75"}

测试结果:
在这里插入图片描述](https://img-blog.csdnimg.cn/direct/aa29c0a074574b4b9f87047382126075.png)
6、测试手动出块generate,这个只在regtest链节点用得上
对应bitcoin-cli命令

./btcoin-cli -generate num(手动出块数,也就是挖矿)

测试地址:http://192.168.25.128:5000/generate
测试参数:

{"count": "10"}

测试结果:
在这里插入图片描述
7、测试其他的wallet方法wallet
距离测试三个方法
对应ord命令:

ord -r wallet wallet_method(钱包方法)

测试参数

{"wallet_method": "inscriptions"}
或者
{"wallet_method": "cardinals"}
或者
{"wallet_method": "outputs"}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
还可以加很多根据需要加减

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1423230.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#使用RabbitMQ-4_路由模式(直连交换机)

简介 RabbitMQ中的路由模式是一种根据Routing Key有条件地将消息筛选后发送给消费者的模式。在路由模式中,生产者向交换机发送消息时,会指定一个Routing Key。交换机接收生产者的消息后,根据消息的Routing Key将其路由到与Routing Key完全匹…

基于腾讯云自然语言处理 NLP服务实现文本情感分析

文章目录 一、前言二、NLP 服务简介三、Python 调用腾讯云 NLP 服务 SDK 构建情感分析处理3.1 开通腾讯云 NLP 服务3.2 创建的腾讯云持久证书(如果已创建请跳过)3.2 在腾讯云服务器中安装 Git 工具以及 Python 环境3.3 安装 qcloudapi-sdk-python3.4 部署…

Linux 文件IO

目录 linux下的文件分类: 文件描述符原理:(底层原理,可跳过) 虚拟文件系统: 内存中的inode与磁盘中的inode open函数 函数原型: 形参列表: 代码: close函数 er…

CTF-WEB的入门真题讲解

EzLogin 第一眼看到这个题目我想着用SQL注入 但是我们先看看具体的情况 我们随便输入admin和密码发现他提升密码不正确 我们查看源代码 发现有二个不一样的第一个是base64 意思I hava no sql 第二个可以看出来是16进制转化为weak通过发现是个弱口令 canyouaccess 如果…

计算机网络-调度算法-2(时间片轮转 优先级调度算法 多级反馈队列调度算法 多级队列调度算法)

文章目录 总览时间片轮转时间片大小为2时间片大小为5若按照先来先服务算法 优先级调度算法例题( 非抢占式优先级调度算法)例题( 抢占式优先级调度算法)补充 思考多级反馈队列调度算法例题 小结多级队列调度算法 总览 时间片轮转 …

排序链表---归并--链表OJ

https://leetcode.cn/problems/sort-list/submissions/499363940/?envTypestudy-plan-v2&envIdtop-100-liked 这里我们直接进阶,用时间复杂度O(nlogn),空间复杂度O(1),来解决。 对于归并,如果自上而下的话,空间复…

sqlmap的使用

2024.1.31 sqlmap支持五种不同的注入模式&#xff1a; 1、布尔盲注2、时间盲注3、报错注入4、联合注入5、堆叠注入 检测注入 GET请求的基本格式 ​python sqlmap.py -u <测试网址> Ps:不知道为什么我的sqlmap使用时前面要加python&#xff0c;而大部分其他教程没提到…

3d模型导入草图大师模型变乱什么原因怎么解决?---模大狮模型网

3D模型在导入草图大师后出现混乱可能有多种原因&#xff0c;以下是一些可能的原因和解决方法&#xff1a; 模型尺寸问题&#xff1a;如果3D模型的尺寸在导入草图大师时与画布尺寸不匹配&#xff0c;可能导致模型混乱。解决方法是在3D建模软件中调整模型的尺寸&#xff0c;使其适…

五大架构风格之一:数据流风格

数据流风格详细介绍 系统架构数据流风格是一种软件体系结构风格&#xff0c;它强调了系统内部不同部分之间的数据流动。这种风格侧重于描述系统中的数据处理过程&#xff0c;以及数据是如何从一个组件传递到另一个组件的。以下是系统架构数据流风格的详细介绍&#xff1a; 1 基…

idea激活教程(2020.1.4及以上版本)

首先点击试用版本&#xff0c;进入软件&#xff0c;再依次进行一下操作 一、在idea的Plugins配置中添加Z大的插件市场 上图中加载出来的插件是默认的&#xff0c;大家不用在意&#xff0c;直接点击“Manage Plugin Repositoryies…”打开配置弹窗 点击号&#xff0c;添加一行…

【C/C++】C/C++编程——整型(一)

整型 C 中的整型是基本的数据类型之一&#xff0c;用于表示没有小数部分的数。这包括正整数、负整数以及零。C 提供了多种整型&#xff0c;以适应不同大小的数值需求和优化内存使用。 整型的种类 C 中的整型可以根据其大小&#xff08;即占用的字节数&#xff09;和能够表示…

【C++】类和对象_1_定义和定义域

1.类的定义&#xff1a; class className {//类体&#xff1a;由成员函数和成员变量组成 };//注意后面的分号class为定义类的关键字&#xff0c;ClassName为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后面分号不能省略。 类体中内容称为类的成员&#x…

Nginx 部署指定文件夹下的项目(本地测试)

1、配置 vue.config.js&#xff0c;指定生成环境的包 //部署生产环境和开发环境下的URLpublicPath: process.env.NODE_ENV production ? "/marketing" : "/",///npm run build 或 varn build 生成文件的日录名称(要利baseUrl的牛产环境路一致)(默认dist…

【每日一题】2670. 找出不同元素数目差数组-2024.1.31

题目&#xff1a; 2670. 找出不同元素数目差数组 给你一个下标从 0 开始的数组 nums &#xff0c;数组长度为 n 。 nums 的 不同元素数目差 数组可以用一个长度为 n 的数组 diff 表示&#xff0c;其中 diff[i] 等于前缀 nums[0, ..., i] 中不同元素的数目 减去 后缀 nums[i …

Django模型(二)

一、更新数据库表结构 不管是新增模型,还是修改已有模型后,只需要执行行命令即可: 1.1、创建迁移 在项目根目录的cmd中运行: $ python manage.py makemigrations model_app备注 model_app是子应用的名称,如果不指定,那么就是对所有 INSTALLED_APPS 中的应用都进行预备…

linux 磁盘标签类型MBR转换为GPT

[rootlocalhost /]# fdisk -l 磁盘 /dev/sda&#xff1a;299.4 GB, 299439751168 字节&#xff0c;584843264 个扇区 Units 扇区 of 1 * 512 512 bytes 扇区大小(逻辑/物理)&#xff1a;512 字节 / 512 字节 I/O 大小(最小/最佳)&#xff1a;512 字节 / 512 字节 磁盘标签类…

软考(高级)在犹豫是否需要报班,不知大家有什么建议?

据我观察&#xff0c;软考是一门可以通过自学掌握的考试&#xff0c;并不争议。然而&#xff0c;尽管如此&#xff0c;我还是不建议大部分同学选择自学&#xff0c;因为相比报班而言&#xff0c;自学的成本反而较高。软考的难度并不低&#xff0c;往年的总体通过率仅为20%&…

注册亚马逊店铺用动态IP可以吗?

注册亚马逊店铺可以用动态IP&#xff0c;只要是独立且干净的网线就没问题&#xff0c;亚马逊规则要求一个IP地址只能出现一个亚马逊店铺&#xff0c;若使用不当会导致关联账户。 固定ip可以给我们的账户带来更多的安全&#xff0c;要知道关联问题是亚马逊上的一个大问题&#…

Sketch 99.5中文 优秀的网站和移动应用设计软件

Sketch for mac用于数字世界的图形设计。在一个屡获殊荣的软件包中提供强大的工具和优雅的界面。因为做美丽的事情应该是一种快乐&#xff0c;而不是负担。 软件下载&#xff1a;Sketch 99.5中文激活版下载 Sketch支持每层多个填充&#xff0c;边框和阴影&#xff1b;具有强大的…

【开源】基于JAVA+Vue+SpringBoot的民宿预定管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用例设计2.2 功能设计2.2.1 租客角色2.2.2 房主角色2.2.3 系统管理员角色 三、系统展示四、核心代码4.1 查询民宿4.2 新增民宿4.3 新增民宿评价4.4 查询留言4.5 新增民宿订单 五、免责说明 一、摘要 1.1 项目介绍 基于…