Skip to content

Commit

Permalink
add bcos3 structs interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
coderkentzhang committed Jul 13, 2023
1 parent 3545b44 commit f8a9135
Show file tree
Hide file tree
Showing 12 changed files with 472 additions and 99 deletions.
20 changes: 19 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,25 @@ __pycache__/
*.py[cod]
*$py.class
bin/contract.ini

bin/*.crt
bin/*.key
bin/*.publickey
bin/
bcos3sdklib/*.lib
bcos3sdklib/*.dll
bcos3sdklib/*.so
bcos3sdklib/*.crt
bcos3sdklib/*.key
bcos3sdklib/*.pem
bcos3sdklib/*.ini
bcos3sdklib/*.sh
bcos3sdklib/*.cnf
cython_tassl_wrap/
contracts/*.abi
contracts/*.bin
contracts/*.json
*.dll
*.lib
# C extensions
*.so

Expand Down
82 changes: 54 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ bcos3_sdk_config.ini配置文件可以和库文件等一起放在 bcos3sdklib目

**重要:**

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

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

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


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

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

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

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

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

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

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

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


## SDK使用示例
## 控制台使用示例

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

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

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

INFO >> call HelloWorld , address: 0x42883e01ac97a3a5ef8a70c290abe0f67913964e, func: get, args:[]
INFO >> call result: 'Hello, FISCO!'


**Event事件回调**
- 针对已经部署在链上某个地址的合约,先注册要监听的事件,当合约被交易调用,且生成事件时,节点可以向客户端推送相应的事件
- 事件定义如有indexed类型的输入,可以指定监听某个特定值作为过滤,如事件定义为 on_set(string name,int indexed value),可以增加一个针对value的topic监听,只监听value=5的事件
- 具体实现参考demo_event_callback.py,使用的命令行为:
```bash
params: contractname address event_name indexed
1. contractname : 合约的文件名,不需要带sol后缀,默认在当前目录的contracts目录下
2. address : 十六进制的合约地址,或者可以为:last,表示采用bin/contract.ini里的记录
3. event_name : 可选,如不设置监听所有事件
4. indexed : 可选,根据event定义里的indexed字段,作为过滤条件)
eg: for contract sample [contracts/HelloEvent.sol], use cmdline:
python demo_event_callback.py HelloEvent last
--listen all event at all indexed :
python demo_event_callback.py HelloEvent last on_set
--listen event on_set(string newname) (no indexed):
python demo_event_callback.py HelloEvent last on_number 5
--listen event on_number(string name,int indexed age), age ONLY 5 :
```


```

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

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

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

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

Python SDK的开源协议为[MIT License](https://opensource.org/licenses/MIT). 详情参考[LICENSE](./LICENSE)
7 changes: 4 additions & 3 deletions bcos3sdk/bcos3callbackfuture.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ def is_empty(self):
def bcos_callback(self, c_resp):
if c_resp is None:
return
# print("bcos_callback-->",c_resp)

resp = BcosResponse(c_resp)

Expand Down Expand Up @@ -69,7 +68,7 @@ def bcos_amop_publish_callback(self, c_resp):
# print(self.error, self.desc)
self.response_queue.put_nowait(resp)

def wait(self, timeout=5):
def wait(self, timeout=5)->(int,BcosResponse):
is_timeout = False
resp = None
try:
Expand All @@ -84,6 +83,8 @@ def display(self):
print(self.detail())

def detail(self):
s = f"queuesize:{self.response_queue.qsize()},reqcontext:{self.context.detail()}"
s = f"queuesize:{self.response_queue.qsize()}"
if self.context is not None:
s += f"reqcontext:{self.context.detail()}"
return s

14 changes: 9 additions & 5 deletions bcos3sdk/bcos3client.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ def init_clib_sdk(self):
privkey = decode_hex(privkey)
#print("privatekey:",privkey)
self.keypair = self.bcossdk.bcos_sdk_create_keypair_by_private_key(self.crypto_enum, privkey, len(privkey))
self.chainid = self.bcossdk.bcos_sdk_get_group_chain_id(self.bcossdk.sdk, s2b(self.group))
chainid = self.bcossdk.bcos_sdk_get_group_chain_id(self.bcossdk.sdk, s2b(self.group))
self.chainid = ctypes.string_at(chainid)
self.bcossdk.bcos_sdk_c_free(chainid)
return 0

def get_last_errormsg(self):
Expand Down Expand Up @@ -183,7 +185,8 @@ def getinfo(self):
info += "group:[{}];".format(self.group)
info += "crypto: [{}];".format(self.config.crypto_type)
address = self.bcossdk.bcos_sdk_get_keypair_address(self.keypair)
info += f"account:[{b2s(address)}];"
info += f"account:[{b2s(ctypes.string_at(address))}];"
self.bcossdk.bcos_sdk_c_free(address)
info += f"peers:[{self.bcos3sdkconfig.peers}];"
if self.sdk_version is None:
self.sdk_version = b2s(self.bcossdk.bcos_sdk_version())
Expand Down Expand Up @@ -460,10 +463,11 @@ def sendRawTransaction(self, to_address, contract_abi, fn_name, args=None,
#------------------------------------
# txdataObj = self.bcossdk.bcos_sdk_create_transaction_data(s2b(self.group), s2b(self.chainid),s2b(to_address), s2b(functiondata), s2b(extra_abi),
# blocklimit )
# txdatahash =self.bcossdk.bcos_sdk_calc_transaction_data_hash(0, txdataObj)
# txdatahash_p =self.bcossdk.bcos_sdk_calc_transaction_data_hash(0, txdataObj) #要free它
# txdatahash = ctypes.string_at(txdatahash_p)
# signres = self.bcossdk.bcos_sdk_sign_transaction_data_hash(self.keypair,txdatahash)
# signedtx = self.bcossdk.bcos_sdk_create_signed_transaction_with_signed_data(txdataObj,signres,txdatahash,0)
# print(signedtx)
# signedtx_p = self.bcossdk.bcos_sdk_create_signed_transaction_with_signed_data(txdataObj,signres,txdatahash,0) #要free它
# print(ctypes.string_at(signedtx) )
# 最后要调用 bcos_sdk_destroy_transaction_data
#------------------------------------------

Expand Down
85 changes: 84 additions & 1 deletion bcos3sdk/bcos3datadef.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import struct
from ctypes import Structure, c_int, c_char_p, create_string_buffer, memmove, c_void_p, c_size_t

from eth_utils import encode_hex


class BcosReqContext(Structure):
_fields_ = [('seq', c_int),
('name', c_char_p),
Expand Down Expand Up @@ -59,7 +62,7 @@ def extract_response(self, c_resp):
self.desc = ""
#print("4)desc:", self.desc)
self.context = c_resp.contents.get_context()
#print("5)context:", self.context)
# print("5)context:", self.context)
return self

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

'''
struct bcos_sdk_c_bytes
{
uint8_t* buffer;
uint32_t length;
};
'''
class BcosBytesCType(Structure):
_fields_ = [('buffer', ctypes.POINTER(c_char_p)),
('length',c_int)
]
def get_input(self):
buffer = getbuffer(self.buffer,self.length)
return buffer.raw
def get_input_hex(self):
raw = self.get_input()
hexstr = encode_hex(raw);
return hexstr

'''
struct bcos_sdk_c_transaction_data
{
int32_t version;
int64_t block_limit;
char* chain_id;
char* group_id;
char* nonce;
char* to;
char* abi;
struct bcos_sdk_c_bytes* input;
};
'''
class BcosTransactionDataCType(Structure):
_fields_ = [('version', c_int),
('block_limit', ctypes.c_int64),
('chain_id', c_char_p),
('group_id', c_char_p),
('nonce', c_char_p),
('to', c_char_p),
('abi', c_char_p),
('input', ctypes.POINTER(BcosBytesCType))
]
def detail(self):
msg = f"version:{self.version},"
msg = msg+ f"block_limit:{self.block_limit},"
msg = msg + f"chain_id:{self.chain_id},"
msg = msg + f"group_id:{self.group_id},"
msg = msg + f"nonce:{self.nonce},"
msg = msg + f"to:{self.to},"
msg = msg + f"abi:{self.abi},"
msg = msg + f"input:{self.input.contents.get_input_hex()}"
return msg

'''
// transaction
struct bcos_sdk_c_transaction
{
struct bcos_sdk_c_transaction_data* transaction_data;
struct bcos_sdk_c_bytes* data_hash;
struct bcos_sdk_c_bytes* signature;
struct bcos_sdk_c_bytes* sender;
int64_t import_time;
int32_t attribute;
char* extra_data;
};
'''
class BcosTransactionCType(Structure):
_fields_ = [
('transaction_data', ctypes.POINTER(BcosTransactionDataCType)),
('data_hash', ctypes.POINTER(BcosBytesCType)),
('signature', ctypes.POINTER(BcosBytesCType)),
('sender', ctypes.POINTER(BcosBytesCType)),
('import_time', ctypes.c_int64),
('attribute', ctypes.c_int32),
('extra_data', ctypes.c_char_p),
]

# bcos sdk返回结构体,ctype定义
class BcosResponseCType(Structure):
Expand Down Expand Up @@ -145,6 +224,10 @@ def b2s(input):
return input
return input

def getbuffer(buffer,size):
pool = create_string_buffer(size)
memmove(pool, buffer, size)
return pool


# bcos sdk回调函数定义
Expand Down
Loading

0 comments on commit f8a9135

Please sign in to comment.