diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..97dfe80 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM fiscoorg/playground:python_sdk + +WORKDIR /python-sdk +RUN apk add --no-cache tzdata && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime + +RUN pip install flask==2.2.5 gunicorn==23.0.0 -i https://mirrors.aliyun.com/pypi/simple/ --no-cache-dir + +COPY . /python-sdk +RUN mv python-fisco-console/* /python-sdk + +EXPOSE 20200 30300 8545 5555 + +CMD ["bash", "run.sh"] diff --git a/Dockerfile.bak b/Dockerfile.bak new file mode 100644 index 0000000..a42de3d --- /dev/null +++ b/Dockerfile.bak @@ -0,0 +1,35 @@ +FROM python:3.7-alpine + +ENV USER root + +ENV PATH /root/.local/bin/:$PATH + +RUN mkdir /python-sdk + +WORKDIR /python-sdk + +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \ + apk update && \ + apk add --no-cache gcc g++ python3 python3-dev py3-pip openssl bash linux-headers libffi-dev openssl-dev curl wget git + +RUN curl -LO https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/v2.9.1/build_chain.sh && chmod u+x build_chain.sh && \ + bash build_chain.sh -l "127.0.0.1:4" -p 30300,20200,8545 + +RUN git clone https://github.com/FISCO-BCOS/python-sdk.git && mv python-sdk/* /python-sdk + +RUN bash init_env.sh -i && \ + cp /python-sdk/nodes/127.0.0.1/sdk/* bin/ && \ + ln -s /root/.local/bin/register-python-argcomplete /bin/register-python-argcomplete && \ + echo "eval \"\$(register-python-argcomplete ./console.py)\"" >> ~/.bashrc && \ + echo "eval \"/python-sdk/nodes/127.0.0.1/start_all.sh\"" >> ~/.bashrc + +COPY requirements.txt /requirements.txt + +RUN pip install -r /requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir + +COPY . /python-sdk +RUN mv python-fisco-console/* /python-sdk + +EXPOSE 20200 30300 8545 5555 + +CMD ["bash", "run.sh"] \ No newline at end of file diff --git a/README.md b/README.md index f59e26b..948dbee 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,43 @@ -# FiscoBcos-PyConsole -FiscoBcos 的区块链浏览器 +# FiscoBcos-Box +FiscoBcos 的区块链盒子,包含 WEB 查看页面, 以及 restFul API ### 简介 -基于python-sdk开发的区块链浏览器,页面参考原始的区块链浏览器 +基于FiscoBcos python-sdk 开发的区块链浏览器,自带 restFul API 接口,无须 Java、MySQL ``` https://github.com/FISCO-BCOS/fisco-bcos-browser.git ``` -点击进入原始 [区块链浏览器](https://github.com/FISCO-BCOS/fisco-bcos-browser.git) -本工程只需要Python3.5 + 即可 - -原始工程需要Python2.7, Java, 以及MySQL.因此进行了简化,不需要任何数据库 #### 项目效果 首页 -![首页截图](https://github.com/Wall-ee/FiscoBcos-PyConsole/blob/master/index.png) +![首页截图](https://github.com/horizon365/FiscoBcos-Box/blob/master/index.png) 交易详情 -![首页截图](https://github.com/Wall-ee/FiscoBcos-PyConsole/blob/master/transaction_detail.png) +![首页截图](https://github.com/horizon365/FiscoBcos-Box/blob/master/transaction_detail.png) -### 环境要求 -1. Fisco Bcos 网络配置完毕 -2. Python3.5+ -3. Flask/Tornado安装 -4. 安装Fisco Bcos 的Python-SDK -``` -https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/python_sdk/install.html -``` -点击进入[Python SDK](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/python_sdk/install.html) -轻量级Python的Http服务器--Flask [官方文档](https://flask.palletsprojects.com/en/master/) -高性能异步非阻塞Python服务器(FaceBook开源)--Tornado [官方文档](http://www.tornadoweb.org/en/stable/) -### 使用方法 +### 使用 docker 快速运行 -1. 安装Fisco Bcos的python-sdk,python-sdk配置规则参照官方教程; +```shell +docker run -p 5555:5555 -d --mount type=volume,source=fisco,target=/root/fisco shujuliuer/fisco_box +``` -2. 将python-fisco-consle下面的所有文件与文件夹一并复制放入python-sdk根目录。其中包括static静态页面目录,以及flask和tornado 的启动文件; +主页访问地址: http://ip:5555/index.html -3. 启动fisco_browser_flask.py 或 fisco_browser_tornado.py 则分别启动flask/tornado 的工程; +#### 注意 +如果使用gunicorn运行服务,第一次由于多个worker都会初使化,导致创建文件失败,程序异常退出。这时docker restart 一次即可。 +尝试过加 preload 以及 明确调用app.app_context 都不能解决问题。 -4. flask主页访问地址: http:ip:5555/index.html +通过 API 接口上链一条数据 +```shell +curl --location 'http://127.0.0.1:5555/sendTrans/rawTrans' \ +--header 'Content-Type: application/json' \ +--data '{"data": "cross the world"}' +``` - tornado主页访问地址: http:ip:5555 或 http:ip:5555/static/index.html ### 区块链浏览器的api详解: @@ -55,7 +48,7 @@ https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/python_sdk 5. 每次部署合约都会生成一个区块,区块内包含一个交易。 -### API详解: +### API 接口: >GET 查询api: @@ -69,6 +62,18 @@ https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/python_sdk /query_info/transaction_detail 根据交易哈希,获取交易详情和交易回执 +/query_info/get_summary_data 根据交易哈希,获取区块详情(包括上一区块、下一区块)和交易详情 + + >POST 上传交易api: -/sendTrans/rawTrans 上传json格式数据,发送交易上链 \ No newline at end of file +/sendTrans/rawTrans 上传json格式数据,发送交易上链 + + +### 开发原理 + +1. 安装Fisco Bcos的python-sdk,python-sdk配置规则参照官方教程; + +2. 将python-fisco-consle下面的所有文件与文件夹一并复制放入python-sdk根目录。其中包括static静态页面目录,以及flask和tornado 的启动文件; + +3. 启动fisco_browser_flask.py 或 fisco_browser_tornado.py 则分别启动flask/tornado 的工程; diff --git a/README_for_cngbdb.md b/README_for_cngbdb.md new file mode 100644 index 0000000..8d2bcdc --- /dev/null +++ b/README_for_cngbdb.md @@ -0,0 +1,25 @@ +Nginx 配置: +```nginx configuration +location /fisco/api/ { +proxy_pass http://127.0.0.1:9518/; +more_clear_headers 'Cache-Control'; +more_set_headers 'Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; +} + +``` + + +# 手动打包docker +```shell +docker build --platform linux/amd64 -t harbor.cngb.org/cngbdb/fisco_box . +``` +# 运行docker +```shell +docker run -p 9518:5555 -d --mount type=volume,source=fisco,target=/root/fisco --label io.portainer.accesscontrol.teams=cngbdb --name fisco harbor.cngb.org/cngbdb/fisco_box +``` +# 修改js中的硬地址,用来匹配nginx代理配置 +```shell +docker exec -it fisco sed -i 's/url: "/url: "\/fisco\/api/g' /python-sdk/static/js/*.js +``` + + diff --git a/python-fisco-console/fisco_browser_flask.py b/python-fisco-console/fisco_browser_flask.py index c1f8c75..fc3fc83 100644 --- a/python-fisco-console/fisco_browser_flask.py +++ b/python-fisco-console/fisco_browser_flask.py @@ -7,7 +7,8 @@ get_transaction_detail_data, send_transaction_get_txhash, get_block_detail_data, - get_data_parser + get_data_parser, + get_summary_data ) app = Flask(__name__, @@ -67,6 +68,13 @@ def send_transaction(): # print("receipt:",receipt) return txhash +# 获取区块以及交易的混合信息 +@app.route('/query_info/get_summary_data', methods=['GET']) +def get_transaction(): + transactionHash = request.args.get('transactionHash', '') + data = get_summary_data(transactionHash) + return json.dumps(data) + if __name__ == "__main__": app.run(port=5555, debug=True, host="0.0.0.0") diff --git a/python-fisco-console/fisco_browser_tornado.py b/python-fisco-console/fisco_browser_tornado.py index feb240f..eae5f8d 100644 --- a/python-fisco-console/fisco_browser_tornado.py +++ b/python-fisco-console/fisco_browser_tornado.py @@ -65,7 +65,7 @@ def __init__(self): handlers = [ (r'/sendTrans/(.*)', TransHandler), (r'/query_info/(.*)', QueryHandler), - (r"/", tornado.web.RedirectHandler, {"url": "/index.html"}), + (r"/", tornado.web.RedirectHandler, {"url": "/static/index.html"}), ] settings = dict( diff --git a/python-fisco-console/process_logic.py b/python-fisco-console/process_logic.py index 4fc9255..133707f 100644 --- a/python-fisco-console/process_logic.py +++ b/python-fisco-console/process_logic.py @@ -47,12 +47,36 @@ def get_to_address(): print("new address : ", result["contractAddress"]) contract_name = os.path.splitext(os.path.basename(abi_file))[0] - # todo 可以放入缓存中 以合约名为key,不需要每次重启都部署合约,每次部署合约会添加一次交易。 to_address = result['contractAddress'] #use new deploy address # to_address = "0xcda895ec53a73fbc3777648cb4c87b38e252f876" #use new deploy address + return to_address, contract_abi, result + +def check_contract(): + """ + 通过 json文件 ,检查合约是否已经部署过,如果没有,则部署一次并生成json文件 + :return: + """ + file_path = '/root/fisco/nodes/contracts.json' + if os.path.isfile(file_path): + with open(file_path, 'r') as load_f: + load_data = json.load(load_f) + to_address, contract_abi, result = load_data['to_address'], load_data['contract_abi'], load_data['result'] + try: + get_transaction_detail_data(result['transactionHash']) + except Exception: + print("\n>>check fail") + os.remove(file_path) + check_contract() + else: + to_address, contract_abi, result = get_to_address() + with open(file_path, 'w') as save_f: + json.dump({ + 'to_address': to_address, + 'contract_abi': contract_abi, + 'result': result, + }, save_f) return to_address, contract_abi - def get_one_block(res): number = int(res.get("number"), 16) add_time = time.strftime("%Y-%m-%d %H:%M:%S", @@ -260,6 +284,62 @@ def get_transaction_list_data(blockNumber, transactionHash, page): } return result +def get_block_hash(blockNumber, blockHash): + block_hash = number = add_time = transaction_number ='--' + try: + block_list = get_block_list_data(blockNumber, blockHash, '')['block_list'] + except: + pass + else: + block_hash = block_list[0]['block_hash'] + number = block_list[0]['number'] + add_time = block_list[0]['add_time'] + transaction_number = block_list[0]['transaction_num'] + return block_hash, number, add_time, transaction_number + +def get_summary_data(transactionHash): + """ +返回值为: +区块信息 + 当前区块(Current block) + 当前区块交易数量(Current block transactions) + 区块哈希值(Block hash) + 前一个区块哈希(Previous block hash) + 后一个区块哈希(Latter block hash) + 区块创建时间(Block creation time) +交易信息 + 交易哈希值(Transaction hash) + 发送者(from):加密 + 接收者(to):加密 + 输入信息(Input):加密 + 交易创建时间(Transaction create time) + +""" + transaction_detail = get_transaction_detail_data(transactionHash) + receipt = transaction_detail['transactionReceipt'] + block_hash = receipt['blockHash'] + block_detail = get_block_detail_data(block_hash) + _, block_number, add_time, transaction_number = get_block_hash('', block_hash) + + data = { + 'block' : { + 'blockNumber': block_number, + 'transactionNumber': transaction_number, + 'blockHash': block_hash, + 'parentHash': block_detail['parentHash'], + 'childHash': get_block_hash(block_number+1, '')[0], + 'time': add_time, + + }, + 'transaction' : { + 'transactionHash': transactionHash, + 'from': receipt['from'], + 'to': receipt['to'], + 'input': receipt['input'], + 'time': get_transaction_list_data('',transactionHash, '')['transaction_list'][0]['time'], + } + } + return data def get_transaction_detail_data(transactionHash): # transactionHash = request.args.get('transactionHash', '') @@ -293,7 +373,6 @@ def get_block_detail_data(blockHash): def send_transaction_get_txhash(requestData): - to_address, contract_abi = get_to_address() # requestData = json.loads(request.get_data().decode()) hash = hashlib.sha1() hash.update(json.dumps(requestData, ensure_ascii=False).encode('utf-8')) @@ -305,4 +384,6 @@ def send_transaction_get_txhash(requestData): receipt = client.sendRawTransactionGetReceipt(to_address, contract_abi, "set", args) txhash = receipt['transactionHash'] # print("receipt:",receipt) - return txhash \ No newline at end of file + return txhash + +to_address, contract_abi = check_contract() diff --git a/python-fisco-console/static/block_detail.html b/python-fisco-console/static/block_detail.html index e8cad3e..bdbd1c0 100644 --- a/python-fisco-console/static/block_detail.html +++ b/python-fisco-console/static/block_detail.html @@ -9,12 +9,13 @@ 区块详情 - + - + +
@@ -23,9 +24,9 @@
@@ -110,4 +108,4 @@
- \ No newline at end of file + diff --git a/python-fisco-console/static/block_list.html b/python-fisco-console/static/block_list.html index cb4067f..0cdb0df 100644 --- a/python-fisco-console/static/block_list.html +++ b/python-fisco-console/static/block_list.html @@ -9,10 +9,11 @@ 区块列表 - + - + +
@@ -21,9 +22,9 @@