Skip to content

Commit f8a9135

Browse files
add bcos3 structs interfaces
1 parent 3545b44 commit f8a9135

12 files changed

Lines changed: 472 additions & 99 deletions

.gitignore

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,25 @@ __pycache__/
33
*.py[cod]
44
*$py.class
55
bin/contract.ini
6-
6+
bin/*.crt
7+
bin/*.key
8+
bin/*.publickey
9+
bin/
10+
bcos3sdklib/*.lib
11+
bcos3sdklib/*.dll
12+
bcos3sdklib/*.so
13+
bcos3sdklib/*.crt
14+
bcos3sdklib/*.key
15+
bcos3sdklib/*.pem
16+
bcos3sdklib/*.ini
17+
bcos3sdklib/*.sh
18+
bcos3sdklib/*.cnf
19+
cython_tassl_wrap/
20+
contracts/*.abi
21+
contracts/*.bin
22+
contracts/*.json
23+
*.dll
24+
*.lib
725
# C extensions
826
*.so
927

README.md

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ bcos3_sdk_config.ini配置文件可以和库文件等一起放在 bcos3sdklib目
212212

213213
**重要:**
214214

215-
最新版本的C语言的SDK库文件可到[文件下载连接](https://fisco-bcos-doc.readthedocs.io/zh_CN/latest/docs/develop/sdk/c_sdk/dylibs.html),下载相应操作系统的库文件
215+
[最新版本的C语言的SDK库文件可到文件下载连接](https://fisco-bcos-doc.readthedocs.io/zh_CN/latest/docs/sdk/c_sdk/dylibs.html),获取相应操作系统的库文件
216216

217217
如windows平台上的bcos-c-sdk.dll,linux平台上的libbcos-c-sdk.so等。
218218

@@ -275,39 +275,39 @@ channel_node_key = "bin/node.key" # 采用channel协议时,需要设置sdk
275275
```
276276

277277

278-
**使用Channel协议访问节点**
278+
## SDK使用简要说明
279279

280-
```bash
281-
# 获取FISCO BCOS节点版本号
282-
./console.py getNodeVersion
283-
```
280+
基于python sdk二次开发,可使用封装好的bcos client对象。
284281

285-
**Event事件回调**
286-
- 针对已经部署在链上某个地址的合约,先注册要监听的事件,当合约被交易调用,且生成事件时,节点可以向客户端推送相应的事件
287-
- 事件定义如有indexed类型的输入,可以指定监听某个特定值作为过滤,如事件定义为 on_set(string name,int indexed value),可以增加一个针对value的topic监听,只监听value=5的事件
288-
- 具体实现参考demo_event_callback.py,使用的命令行为:
289-
```bash
290-
params: contractname address event_name indexed
291-
1. contractname : 合约的文件名,不需要带sol后缀,默认在当前目录的contracts目录下
292-
2. address : 十六进制的合约地址,或者可以为:last,表示采用bin/contract.ini里的记录
293-
3. event_name : 可选,如不设置监听所有事件
294-
4. indexed : 可选,根据event定义里的indexed字段,作为过滤条件)
282+
根据FISCO BCOS是2.x或3.x版本,分别封装:
295283

296-
eg: for contract sample [contracts/HelloEvent.sol], use cmdline:
284+
[client/bcosclient.py](client/bcosclient.py)对应2.x版本,其使用示例参见 [tests/testclient.py](tests/testclient.py)
297285

298-
python demo_event_callback.py HelloEvent last
299-
--listen all event at all indexed :
286+
[bcos3sdk/bcos3client.py](bcos3sdk/bcos3client.py)对应3.x版本,其使用示例参见 [tests/testbcos3client.py](tests/testbcos3client.py)
300287

301-
python demo_event_callback.py HelloEvent last on_set
302-
--listen event on_set(string newname) (no indexed):
288+
一般的使用次序
289+
```bash
290+
1.import不同版本的client对象
291+
2.指定配置类
292+
3.初始化客户端client
293+
4.加载合约的abi定义
294+
5.用call/sendRawTransaction等方法调用合约
295+
6.处理返回的结果
296+
```
303297

304-
python demo_event_callback.py HelloEvent last on_number 5
305-
--listen event on_number(string name,int indexed age), age ONLY 5 :
298+
或者调用其他链RPC接口的额方法,如getBlockNumber等,参见客户端代码实现、以及对照FISCO BCOS不同版本的RPC接口定义即可。
299+
代码比较直观,直接查看示例代码即可。
306300

301+
```bash
302+
注意:
303+
对合约的只读接口(view或constant),使用call方法,
304+
对合约的交易类接口,应使用sendRawTransaction/sendRawTransactionGetReceipt方法
305+
这里和FISCO BCOS 自带的控制台有一些不同,控制台对两种类型的合约方法都用call调用,以简化操作,
306+
python-sdk保留原始接口RPC的定义风格,对两种类型的方法进行区格
307+
python-sdk自带的控制台同理,对不同类型的方法,分别使用call或sendtx
307308
```
308309

309-
310-
## SDK使用示例
310+
## 控制台使用示例
311311

312312
:FISCO BCOS 3.0的控制台文件是** console3.py**,使用方法基本同FISCO BCOS 2.0,主要是查询类接口有数量上的区别
313313

@@ -323,7 +323,7 @@ params: contractname address event_name indexed
323323
> **windows环境下执行console2/3.py请使用`.\console2/3.py`或者`python console2/3.py`**
324324
325325
```bash
326-
# 查看SDK使用方法
326+
# 查看控制台使用方法
327327
./console.py usage
328328

329329
# 获取区块高度
@@ -394,6 +394,33 @@ INFO >> user input : ['call', 'HelloWorld', '0x42883e01ac97a3a5ef8a70c290abe0f67
394394

395395
INFO >> call HelloWorld , address: 0x42883e01ac97a3a5ef8a70c290abe0f67913964e, func: get, args:[]
396396
INFO >> call result: 'Hello, FISCO!'
397+
398+
399+
**Event事件回调**
400+
- 针对已经部署在链上某个地址的合约,先注册要监听的事件,当合约被交易调用,且生成事件时,节点可以向客户端推送相应的事件
401+
- 事件定义如有indexed类型的输入,可以指定监听某个特定值作为过滤,如事件定义为 on_set(string name,int indexed value),可以增加一个针对value的topic监听,只监听value=5的事件
402+
- 具体实现参考demo_event_callback.py,使用的命令行为:
403+
```bash
404+
params: contractname address event_name indexed
405+
1. contractname : 合约的文件名,不需要带sol后缀,默认在当前目录的contracts目录下
406+
2. address : 十六进制的合约地址,或者可以为:last,表示采用bin/contract.ini里的记录
407+
3. event_name : 可选,如不设置监听所有事件
408+
4. indexed : 可选,根据event定义里的indexed字段,作为过滤条件)
409+
410+
eg: for contract sample [contracts/HelloEvent.sol], use cmdline:
411+
412+
python demo_event_callback.py HelloEvent last
413+
--listen all event at all indexed :
414+
415+
python demo_event_callback.py HelloEvent last on_set
416+
--listen event on_set(string newname) (no indexed):
417+
418+
python demo_event_callback.py HelloEvent last on_number 5
419+
--listen event on_number(string name,int indexed age), age ONLY 5 :
420+
421+
```
422+
423+
397424
```
398425

399426
## 控制台输入复杂数据类型概要说明
@@ -460,9 +487,8 @@ source ~/.bashrc
460487

461488
**FISCO BCOS开源社区**是国内活跃的开源社区,社区长期为机构和个人开发者提供各类支持与帮助。已有来自各行业的数千名技术爱好者在研究和使用FISCO BCOS。如您对FISCO BCOS开源技术及应用感兴趣,欢迎加入社区获得更多支持与帮助。
462489

463-
![](https://media.githubusercontent.com/media/FISCO-BCOS/LargeFiles/master/images/QR_image.png)
490+
![](images/qr_code1.png)
464491

465492
## License
466-
![license](https://img.shields.io/github/license/FISCO-BCOS/python-sdk.svg)
467493

468494
Python SDK的开源协议为[MIT License](https://opensource.org/licenses/MIT). 详情参考[LICENSE](./LICENSE)

bcos3sdk/bcos3callbackfuture.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ def is_empty(self):
4040
def bcos_callback(self, c_resp):
4141
if c_resp is None:
4242
return
43-
# print("bcos_callback-->",c_resp)
4443

4544
resp = BcosResponse(c_resp)
4645

@@ -69,7 +68,7 @@ def bcos_amop_publish_callback(self, c_resp):
6968
# print(self.error, self.desc)
7069
self.response_queue.put_nowait(resp)
7170

72-
def wait(self, timeout=5):
71+
def wait(self, timeout=5)->(int,BcosResponse):
7372
is_timeout = False
7473
resp = None
7574
try:
@@ -84,6 +83,8 @@ def display(self):
8483
print(self.detail())
8584

8685
def detail(self):
87-
s = f"queuesize:{self.response_queue.qsize()},reqcontext:{self.context.detail()}"
86+
s = f"queuesize:{self.response_queue.qsize()}"
87+
if self.context is not None:
88+
s += f"reqcontext:{self.context.detail()}"
8889
return s
8990

bcos3sdk/bcos3client.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ def init_clib_sdk(self):
126126
privkey = decode_hex(privkey)
127127
#print("privatekey:",privkey)
128128
self.keypair = self.bcossdk.bcos_sdk_create_keypair_by_private_key(self.crypto_enum, privkey, len(privkey))
129-
self.chainid = self.bcossdk.bcos_sdk_get_group_chain_id(self.bcossdk.sdk, s2b(self.group))
129+
chainid = self.bcossdk.bcos_sdk_get_group_chain_id(self.bcossdk.sdk, s2b(self.group))
130+
self.chainid = ctypes.string_at(chainid)
131+
self.bcossdk.bcos_sdk_c_free(chainid)
130132
return 0
131133

132134
def get_last_errormsg(self):
@@ -183,7 +185,8 @@ def getinfo(self):
183185
info += "group:[{}];".format(self.group)
184186
info += "crypto: [{}];".format(self.config.crypto_type)
185187
address = self.bcossdk.bcos_sdk_get_keypair_address(self.keypair)
186-
info += f"account:[{b2s(address)}];"
188+
info += f"account:[{b2s(ctypes.string_at(address))}];"
189+
self.bcossdk.bcos_sdk_c_free(address)
187190
info += f"peers:[{self.bcos3sdkconfig.peers}];"
188191
if self.sdk_version is None:
189192
self.sdk_version = b2s(self.bcossdk.bcos_sdk_version())
@@ -460,10 +463,11 @@ def sendRawTransaction(self, to_address, contract_abi, fn_name, args=None,
460463
#------------------------------------
461464
# txdataObj = self.bcossdk.bcos_sdk_create_transaction_data(s2b(self.group), s2b(self.chainid),s2b(to_address), s2b(functiondata), s2b(extra_abi),
462465
# blocklimit )
463-
# txdatahash =self.bcossdk.bcos_sdk_calc_transaction_data_hash(0, txdataObj)
466+
# txdatahash_p =self.bcossdk.bcos_sdk_calc_transaction_data_hash(0, txdataObj) #要free它
467+
# txdatahash = ctypes.string_at(txdatahash_p)
464468
# signres = self.bcossdk.bcos_sdk_sign_transaction_data_hash(self.keypair,txdatahash)
465-
# signedtx = self.bcossdk.bcos_sdk_create_signed_transaction_with_signed_data(txdataObj,signres,txdatahash,0)
466-
# print(signedtx)
469+
# signedtx_p = self.bcossdk.bcos_sdk_create_signed_transaction_with_signed_data(txdataObj,signres,txdatahash,0) #要free它
470+
# print(ctypes.string_at(signedtx) )
467471
# 最后要调用 bcos_sdk_destroy_transaction_data
468472
#------------------------------------------
469473

bcos3sdk/bcos3datadef.py

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import struct
33
from ctypes import Structure, c_int, c_char_p, create_string_buffer, memmove, c_void_p, c_size_t
44

5+
from eth_utils import encode_hex
6+
7+
58
class BcosReqContext(Structure):
69
_fields_ = [('seq', c_int),
710
('name', c_char_p),
@@ -59,7 +62,7 @@ def extract_response(self, c_resp):
5962
self.desc = ""
6063
#print("4)desc:", self.desc)
6164
self.context = c_resp.contents.get_context()
62-
#print("5)context:", self.context)
65+
# print("5)context:", self.context)
6366
return self
6467

6568
def detail(self):
@@ -69,6 +72,82 @@ def detail(self):
6972
str = str + (" | context:({}),{},[{}]".format(c.seq, b2s(c.name), b2s(c.msg)))
7073
return str
7174

75+
'''
76+
struct bcos_sdk_c_bytes
77+
{
78+
uint8_t* buffer;
79+
uint32_t length;
80+
};
81+
'''
82+
class BcosBytesCType(Structure):
83+
_fields_ = [('buffer', ctypes.POINTER(c_char_p)),
84+
('length',c_int)
85+
]
86+
def get_input(self):
87+
buffer = getbuffer(self.buffer,self.length)
88+
return buffer.raw
89+
def get_input_hex(self):
90+
raw = self.get_input()
91+
hexstr = encode_hex(raw);
92+
return hexstr
93+
94+
'''
95+
struct bcos_sdk_c_transaction_data
96+
{
97+
int32_t version;
98+
int64_t block_limit;
99+
char* chain_id;
100+
char* group_id;
101+
char* nonce;
102+
char* to;
103+
char* abi;
104+
struct bcos_sdk_c_bytes* input;
105+
};
106+
'''
107+
class BcosTransactionDataCType(Structure):
108+
_fields_ = [('version', c_int),
109+
('block_limit', ctypes.c_int64),
110+
('chain_id', c_char_p),
111+
('group_id', c_char_p),
112+
('nonce', c_char_p),
113+
('to', c_char_p),
114+
('abi', c_char_p),
115+
('input', ctypes.POINTER(BcosBytesCType))
116+
]
117+
def detail(self):
118+
msg = f"version:{self.version},"
119+
msg = msg+ f"block_limit:{self.block_limit},"
120+
msg = msg + f"chain_id:{self.chain_id},"
121+
msg = msg + f"group_id:{self.group_id},"
122+
msg = msg + f"nonce:{self.nonce},"
123+
msg = msg + f"to:{self.to},"
124+
msg = msg + f"abi:{self.abi},"
125+
msg = msg + f"input:{self.input.contents.get_input_hex()}"
126+
return msg
127+
128+
'''
129+
// transaction
130+
struct bcos_sdk_c_transaction
131+
{
132+
struct bcos_sdk_c_transaction_data* transaction_data;
133+
struct bcos_sdk_c_bytes* data_hash;
134+
struct bcos_sdk_c_bytes* signature;
135+
struct bcos_sdk_c_bytes* sender;
136+
int64_t import_time;
137+
int32_t attribute;
138+
char* extra_data;
139+
};
140+
'''
141+
class BcosTransactionCType(Structure):
142+
_fields_ = [
143+
('transaction_data', ctypes.POINTER(BcosTransactionDataCType)),
144+
('data_hash', ctypes.POINTER(BcosBytesCType)),
145+
('signature', ctypes.POINTER(BcosBytesCType)),
146+
('sender', ctypes.POINTER(BcosBytesCType)),
147+
('import_time', ctypes.c_int64),
148+
('attribute', ctypes.c_int32),
149+
('extra_data', ctypes.c_char_p),
150+
]
72151

73152
# bcos sdk返回结构体,ctype定义
74153
class BcosResponseCType(Structure):
@@ -145,6 +224,10 @@ def b2s(input):
145224
return input
146225
return input
147226

227+
def getbuffer(buffer,size):
228+
pool = create_string_buffer(size)
229+
memmove(pool, buffer, size)
230+
return pool
148231

149232

150233
# bcos sdk回调函数定义

0 commit comments

Comments
 (0)