Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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"]
35 changes: 35 additions & 0 deletions Dockerfile.bak
Original file line number Diff line number Diff line change
@@ -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"]
61 changes: 33 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -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详解:

Expand All @@ -55,7 +48,7 @@ https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/python_sdk
5. 每次部署合约都会生成一个区块,区块内包含一个交易。


### API详解
### API 接口

>GET 查询api:

Expand All @@ -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格式数据,发送交易上链
/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 的工程;
25 changes: 25 additions & 0 deletions README_for_cngbdb.md
Original file line number Diff line number Diff line change
@@ -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
```


10 changes: 9 additions & 1 deletion python-fisco-console/fisco_browser_flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__,
Expand Down Expand Up @@ -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")
2 changes: 1 addition & 1 deletion python-fisco-console/fisco_browser_tornado.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
89 changes: 85 additions & 4 deletions python-fisco-console/process_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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', '')
Expand Down Expand Up @@ -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'))
Expand All @@ -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
return txhash

to_address, contract_abi = check_contract()
34 changes: 16 additions & 18 deletions python-fisco-console/static/block_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
<title>区块详情</title>
<link href="./css/all.css" rel="stylesheet">
<link href="./css/public.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
<script src="https://www.jq22.com/jquery/vue2.6.10.min.js"></script>
<!-- <script src="https://unpkg.com/axios/dist/axios.min.js"></script>-->
<script src="./js/axios.min.js"></script>
<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<link href="./json-viewer/jquery.json-viewer.css" rel="stylesheet">
<script src="./json-viewer/jquery.json-viewer.js"></script>
<link rel="icon" href="/gs/favicon.ico" type="image/x-icon">
</head>
<body>
<div id="app" class="web-font">
Expand All @@ -23,9 +24,9 @@
<div>
<div class="nav-header">
<div class="container">
<div class="logo">
<a href="./index.html"><img src="./pic/fisco-bcos-logo.3a5e45c.png" class="image" style="width: 170px;"></a>
</div>
<!-- <div class="logo">-->
<!-- <a href="./index.html"><img src="./pic/fisco-bcos-logo.3a5e45c.png" class="image" style="width: 170px;"></a>-->
<!-- </div>-->
<!-- <div class="nav-menu" style="float: left;">-->
<!-- <div class="nav-menu-item nav-item" style="display: inline-block; width: 160px; text-align: right;">-->
<!-- <span>1</span>-->
Expand Down Expand Up @@ -90,24 +91,21 @@
</div>
</div>
<div data-v-a36316e4="" class="hash-content-info">
<!-- <div data-v-a36316e4="" class="container" >-->
<!-- <div data-v-a36316e4="" class="content">-->
<!-- <div data-v-a36316e4="">-->
<!-- <div data-v-a36316e4="" class="jv-container jv-light">-->
<!-- <div class="jv-code">-->
<div class="jv-node" id="id-div-detail" style="width: 95.8%;word-wrap:break-word;word-break:break-all;overflow: hidden;background: #d1dbe5">
<!-- {{ block_detail }}-->
<div data-v-a36316e4="" class="container" >
<div data-v-a36316e4="" class="content">
<div data-v-a36316e4="">
<div data-v-a36316e4="" class="jv-container jv-light">
<div class="jv-node" id="id-div-detail" style="width: 95.8%;word-wrap:break-word;word-break:break-all;overflow: hidden;background: rgb(249, 249, 249)">
</div>
<!-- </div> -->
<!-- </div> -->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div>
</div>
</div>
</div>
</div>
</div>
</div> <!---->
</div>
</div>
<script src="./js/block_detail.js"></script>
</body>
</html>
</html>
Loading