From 7bcf4bb4c7e8991647c347f7402b4c33be3b1317 Mon Sep 17 00:00:00 2001
From: "alexey.stratulat" <alexey.stratulat@demlabs.net>
Date: Mon, 16 Dec 2019 21:51:34 +0700
Subject: [PATCH] [+] Added wrapping dap_chain_datum_tx

---
 include/wrapping_dap_chain_datum_tx.h | 277 ++++++++++++++++++++++++++
 src/wrapping_dap_chain_datum_tx.c     | 201 +++++++++++++++++++
 2 files changed, 478 insertions(+)
 create mode 100644 include/wrapping_dap_chain_datum_tx.h
 create mode 100644 src/wrapping_dap_chain_datum_tx.c

diff --git a/include/wrapping_dap_chain_datum_tx.h b/include/wrapping_dap_chain_datum_tx.h
new file mode 100644
index 00000000..68330699
--- /dev/null
+++ b/include/wrapping_dap_chain_datum_tx.h
@@ -0,0 +1,277 @@
+#ifndef _WRAPPING_DAP_CHAIN_DATUM_TX_
+#define _WRAPPING_DAP_CHAIN_DATUM_TX_
+
+#include "Python.h"
+#include "wrapping_dap_chain_common.h"
+#include "libdap_crypto_key_python.h"
+#include "dap_chain_datum_tx_out_cond.h"
+#include "wrapping_dap_hash.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* DAP chain tx iter type */
+typedef struct PyDapChainTxItemType{
+    PyObject_HEAD
+}PyDapChainTxItemTypeObject;
+
+PyObject *TX_ITEM_TYPE_IN_PY(void);
+PyObject *TX_ITEM_TYPE_OUT_PY(void);
+PyObject *TX_ITEM_TYPE_PKEY_PY(void);
+PyObject *TX_ITEM_TYPE_SIG_PY(void);
+PyObject *TX_ITEM_TYPE_TOKEN_PY(void);
+PyObject *TX_ITEM_TYPE_IN_COND_PY(void);
+PyObject *TX_ITEM_TYPE_OUT_COND_PY(void);
+PyObject *TX_ITEM_TYPE_RECEIPT_PY(void);
+
+static PyMethodDef PyDapChainTxItemTypeObjectMethods[] ={
+    {"TX_ITEM_TYPE_IN", (PyCFunction)TX_ITEM_TYPE_IN_PY, METH_NOARGS | METH_STATIC, ""},
+    {"TX_ITEM_TYPE_OUT", (PyCFunction)TX_ITEM_TYPE_OUT_PY, METH_NOARGS | METH_STATIC, ""},
+    {"TX_ITEM_TYPE_PKEY", (PyCFunction)TX_ITEM_TYPE_PKEY_PY, METH_NOARGS | METH_STATIC, ""},
+    {"TX_ITEM_TYPE_SIG", (PyCFunction)TX_ITEM_TYPE_SIG_PY, METH_NOARGS | METH_STATIC, ""},
+    {"TX_ITEM_TYPE_TOKEN", (PyCFunction)TX_ITEM_TYPE_TOKEN_PY, METH_NOARGS | METH_STATIC, ""},
+    {"TX_ITEM_TYPE_IN_COND", (PyCFunction)TX_ITEM_TYPE_IN_COND_PY, METH_NOARGS | METH_STATIC, ""},
+    {"TX_ITEM_TYPE_OUT_COND", (PyCFunction)TX_ITEM_TYPE_OUT_COND_PY, METH_NOARGS | METH_STATIC, ""},
+    {"TX_ITEM_TYPE_RECEIPT", (PyCFunction)TX_ITEM_TYPE_RECEIPT_PY,
+                                                            METH_NOARGS | METH_STATIC, ""},
+    {NULL, NULL, 0, NULL}
+};
+
+static PyTypeObject DapChainTxItemObject_DapChainTxItemTypeObjectType = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "CellFrame.Chain.TxItemType",        /* tp_name */
+    sizeof(PyDapChainTxItemTypeObject), /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    0,                                  /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    0,                                  /* tp_reserved */
+    0,                                  /* tp_repr */
+    0,                                  /* tp_as_number */
+    0,                                  /* tp_as_sequence */
+    0,                                  /* tp_as_mapping */
+    0,                                  /* tp_hash  */
+    0,                                  /* tp_call */
+    0,                                  /* tp_str */
+    0,                                  /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+        Py_TPFLAGS_BASETYPE,            /* tp_flags */
+    "Chain tx item type object",        /* tp_doc */
+    0,		                            /* tp_traverse */
+    0,		                            /* tp_clear */
+    0,		                            /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    0,		                            /* tp_iter */
+    0,		                            /* tp_iternext */
+    PyDapChainTxItemTypeObjectMethods,  /* tp_methods */
+    0,                                  /* tp_members */
+    0,                                  /* tp_getset */
+    0,                                  /* tp_base */
+    0,                                  /* tp_dict */
+    0,                                  /* tp_descr_get */
+    0,                                  /* tp_descr_set */
+    0,                                  /* tp_dictoffset */
+    0,                                  /* tp_init */
+    0,                                  /* tp_alloc */
+    PyType_GenericNew,                  /* tp_new */
+};
+
+/* -------------------------------------- */
+
+/* DAP chain tx cond type */
+typedef struct PyDapChainTxCondType{
+    PyObject_HEAD
+    dap_chain_tx_cond_type_t tx_cond_type_t;
+}PyDapChainTxCondTypeObject;
+
+PyObject *COND_SERVICE_PROVIDE_PY();
+PyObject *COND_SERVICE_BILL_PY();
+
+PyMethodDef DapChainTxCondTypeMethods[] = {
+    {"COND_SERVICE_PROVIDE", COND_SERVICE_PROVIDE_PY, METH_NOARGS | METH_STATIC, ""},
+    {"COND_SERVICE_BILL", COND_SERVICE_BILL_PY, METH_NOARGS | METH_STATIC, ""},
+    {NULL, NULL,0, NULL}
+};
+
+static PyTypeObject DapChainTxCondType_DapChainTxCondTypeObject = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "CellFrame.Chain.TxCondType",       /* tp_name */
+    sizeof(PyDapChainTxCondTypeObject),/* tp_basicsize */
+    0,                               /* tp_itemsize */
+    0,                               /* tp_dealloc */
+    0,                               /* tp_print */
+    0,                               /* tp_getattr */
+    0,                               /* tp_setattr */
+    0,                               /* tp_reserved */
+    0,                               /* tp_repr */
+    0,                               /* tp_as_number */
+    0,                               /* tp_as_sequence */
+    0,                               /* tp_as_mapping */
+    0,                               /* tp_hash  */
+    0,                               /* tp_call */
+    0,                               /* tp_str */
+    0,                               /* tp_getattro */
+    0,                               /* tp_setattro */
+    0,                               /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+        Py_TPFLAGS_BASETYPE,         /* tp_flags */
+    "Chain tx cond type object",             /* tp_doc */
+    0,		                         /* tp_traverse */
+    0,		                         /* tp_clear */
+    0,		                         /* tp_richcompare */
+    0,                               /* tp_weaklistoffset */
+    0,		                         /* tp_iter */
+    0,		                         /* tp_iternext */
+    DapChainTxCondTypeMethods,       /* tp_methods */
+    0,                               /* tp_members */
+    0,                               /* tp_getset */
+    0,                               /* tp_base */
+    0,                               /* tp_dict */
+    0,                               /* tp_descr_get */
+    0,                               /* tp_descr_set */
+    0,                               /* tp_dictoffset */
+    0,                               /* tp_init */
+    0,                               /* tp_alloc */
+    PyType_GenericNew,               /* tp_new */
+};
+
+/* -------------------------------------- */
+
+/* DAP chain datum tx */
+typedef struct PyDapChainDatumTx{
+    PyObject_HEAD
+    dap_chain_datum_tx_t *datum_tx;
+}PyDapChainDatumTxObject;
+
+PyObject *PyDapChainDatumTxObject_create(PyTypeObject *type_object, PyObject *args, PyObject *kwds);
+void PyDapChainDatumTxObject_delete(PyDapChainDatumTxObject* datumTx);
+PyObject *dap_chain_datum_tx_get_size_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_tx_add_item_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_tx_add_in_item_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_tx_add_in_cond_item_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_tx_add_out_item_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_tx_add_out_cond_item_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_tx_add_sign_item_py(PyObject *self, PyObject *args);
+PyObject *dap_chain_datum_tx_verify_sign_py(PyObject *self, PyObject *args);
+
+static dap_chain_datum_tx_t **PyListToDapChainDatumTxArray(PyObject *a_in_obj);
+static PyObject* DapChainDatumTxArrayToPyList(dap_chain_datum_tx_t** datum_txs);
+
+
+static PyMethodDef PyDapChainDatumTxObjectMethods[] ={
+    {"getSize", (PyCFunction)dap_chain_datum_tx_get_size_py, METH_VARARGS, ""},
+    {"addItem", (PyCFunction)dap_chain_datum_tx_add_item_py, METH_VARARGS | METH_STATIC, ""},
+    {"addInItem", (PyCFunction)dap_chain_datum_tx_add_in_item_py, METH_VARARGS | METH_STATIC, ""},
+    {"addInCondItem", (PyCFunction)dap_chain_datum_tx_add_in_cond_item_py, METH_VARARGS | METH_STATIC, ""},
+    {"addOutItem", (PyCFunction)dap_chain_datum_tx_add_out_item_py, METH_VARARGS | METH_STATIC, ""},
+    {"addOutCond", (PyCFunction)dap_chain_datum_tx_add_out_cond_item_py, METH_VARARGS | METH_STATIC, ""},
+    {"addSignItem", (PyCFunction)dap_chain_datum_tx_add_sign_item_py, METH_VARARGS | METH_STATIC, ""},
+    {"verifySign", (PyCFunction)dap_chain_datum_tx_verify_sign_py, METH_VARARGS, ""},
+    {NULL, NULL, 0, NULL}
+};
+
+static PyTypeObject DapChainDatumTx_DapChainDatumTxObjectType = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "CellFrame.Chain.DatumTx",                      /* tp_name */
+    sizeof(PyDapChainDatumTxObject),               /* tp_basicsize */
+    0,                                             /* tp_itemsize */
+    (destructor)PyDapChainDatumTxObject_delete,    /* tp_dealloc */
+    0,                                              /* tp_print */
+    0,                                              /* tp_getattr */
+    0,                                              /* tp_setattr */
+    0,                                              /* tp_reserved */
+    0,                                              /* tp_repr */
+    0,                                              /* tp_as_number */
+    0,                                              /* tp_as_sequence */
+    0,                                              /* tp_as_mapping */
+    0,                                              /* tp_hash  */
+    0,                                              /* tp_call */
+    0,                                              /* tp_str */
+    0,                                              /* tp_getattro */
+    0,                                              /* tp_setattro */
+    0,                                              /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+        Py_TPFLAGS_BASETYPE,                        /* tp_flags */
+    "Chain datum tx object",                        /* tp_doc */
+    0,		                                        /* tp_traverse */
+    0,		                                        /* tp_clear */
+    0,		                                        /* tp_richcompare */
+    0,                                              /* tp_weaklistoffset */
+    0,		                                        /* tp_iter */
+    0,		                                        /* tp_iternext */
+    PyDapChainDatumTxObjectMethods,                 /* tp_methods */
+    0,                                              /* tp_members */
+    0,                                              /* tp_getset */
+    0,                                              /* tp_base */
+    0,                                              /* tp_dict */
+    0,                                              /* tp_descr_get */
+    0,                                              /* tp_descr_set */
+    0,                                              /* tp_dictoffset */
+    0,                                              /* tp_init */
+    0,                                              /* tp_alloc */
+    PyDapChainDatumTxObject_create,                 /* tp_new */
+};
+
+/* -------------------------------------- */
+
+typedef struct PyDapChainTxOutCond{
+    PyObject_HEAD
+    dap_chain_tx_out_cond_t *out_cond;
+}PyDapChainTxOutCondObject;
+
+static PyTypeObject DapChainTxOutCond_DapChainTxOutCondObjectType = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "CellFrame.Chain.TxOutCond",                      /* tp_name */
+    sizeof(PyDapChainTxOutCondObject),               /* tp_basicsize */
+    0,                                             /* tp_itemsize */
+    0,                                             /* tp_dealloc */
+    0,                                              /* tp_print */
+    0,                                              /* tp_getattr */
+    0,                                              /* tp_setattr */
+    0,                                              /* tp_reserved */
+    0,                                              /* tp_repr */
+    0,                                              /* tp_as_number */
+    0,                                              /* tp_as_sequence */
+    0,                                              /* tp_as_mapping */
+    0,                                              /* tp_hash  */
+    0,                                              /* tp_call */
+    0,                                              /* tp_str */
+    0,                                              /* tp_getattro */
+    0,                                              /* tp_setattro */
+    0,                                              /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+        Py_TPFLAGS_BASETYPE,                        /* tp_flags */
+    "Chain tx out cond object",                        /* tp_doc */
+    0,		                                        /* tp_traverse */
+    0,		                                        /* tp_clear */
+    0,		                                        /* tp_richcompare */
+    0,                                              /* tp_weaklistoffset */
+    0,		                                        /* tp_iter */
+    0,		                                        /* tp_iternext */
+    0,                                              /* tp_methods */
+    0,                                              /* tp_members */
+    0,                                              /* tp_getset */
+    0,                                              /* tp_base */
+    0,                                              /* tp_dict */
+    0,                                              /* tp_descr_get */
+    0,                                              /* tp_descr_set */
+    0,                                              /* tp_dictoffset */
+    0,                                              /* tp_init */
+    0,                                              /* tp_alloc */
+    PyType_GenericNew,                              /* tp_new */
+};
+
+dap_chain_tx_out_cond_t **PyListToDapChainTxOutCond(PyObject *list);
+PyObject *DapChainTxOutCondObjectToPyList(dap_chain_tx_out_cond_t **out_cond);
+
+/* -------------------------------------- */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_WRAPPING_DAP_CHAIN_DATUM_TX_
diff --git a/src/wrapping_dap_chain_datum_tx.c b/src/wrapping_dap_chain_datum_tx.c
new file mode 100644
index 00000000..4a814986
--- /dev/null
+++ b/src/wrapping_dap_chain_datum_tx.c
@@ -0,0 +1,201 @@
+#include "wrapping_dap_chain_datum_tx.h"
+
+/* DAP chain tx iter type */
+
+PyObject *TX_ITEM_TYPE_IN_PY(void){
+    return PyLong_FromLong(TX_ITEM_TYPE_IN);
+}
+PyObject *TX_ITEM_TYPE_OUT_PY(void){
+        return PyLong_FromLong(TX_ITEM_TYPE_OUT);
+}
+PyObject *TX_ITEM_TYPE_PKEY_PY(void){
+        return PyLong_FromLong(TX_ITEM_TYPE_PKEY);
+}
+PyObject *TX_ITEM_TYPE_SIG_PY(void){
+        return PyLong_FromLong(TX_ITEM_TYPE_SIG);
+}
+PyObject *TX_ITEM_TYPE_TOKEN_PY(void){
+        return PyLong_FromLong(TX_ITEM_TYPE_TOKEN);
+}
+PyObject *TX_ITEM_TYPE_IN_COND_PY(void){
+        return PyLong_FromLong(TX_ITEM_TYPE_IN_COND);
+}
+PyObject *TX_ITEM_TYPE_OUT_COND_PY(void){
+        return PyLong_FromLong(TX_ITEM_TYPE_OUT_COND);
+}
+PyObject *TX_ITEM_TYPE_RECEIPT_PY(void){
+        return PyLong_FromLong(TX_ITEM_TYPE_RECEIPT);
+}
+
+/* -------------------------------------- */
+
+/* DAP chain tx cond type */
+PyObject *COND_SERVICE_PROVIDE_PY(){
+    PyObject *obj = _PyObject_New(&DapChainTxCondType_DapChainTxCondTypeObject);
+    ((PyDapChainTxCondTypeObject*)obj)->tx_cond_type_t = COND_SERVICE_PROVIDE;
+    return Py_BuildValue("O", obj);
+}
+PyObject *COND_SERVICE_BILL_PY(){
+    PyObject *obj = _PyObject_New(&DapChainTxCondType_DapChainTxCondTypeObject);
+    ((PyDapChainTxCondTypeObject*)obj)->tx_cond_type_t = COND_SERVICE_BILL;
+    return Py_BuildValue("O", obj);
+}
+/* -------------------------------------- */
+
+/* DAP chain datum tx */
+PyObject *PyDapChainDatumTxObject_create(PyTypeObject *type_object, PyObject *args, PyObject *kwds){
+    PyDapChainDatumTxObject *obj = (PyDapChainDatumTxObject*)PyType_GenericNew(type_object, args, kwds);
+    obj->datum_tx = dap_chain_datum_tx_create();
+    return (PyObject *)obj;
+}
+void PyDapChainDatumTxObject_delete(PyDapChainDatumTxObject* datumTx){
+    dap_chain_datum_tx_delete(datumTx->datum_tx);
+    Py_TYPE(datumTx)->tp_free((PyObject*)datumTx);
+}
+
+PyObject *dap_chain_datum_tx_get_size_py(PyObject *self, PyObject *args){
+    size_t size = dap_chain_datum_tx_get_size(((PyDapChainDatumTxObject*)self)->datum_tx);
+    return PyLong_FromSize_t(size);
+}
+PyObject *dap_chain_datum_tx_add_item_py(PyObject *self, PyObject *args){
+    PyObject *in_obj;
+    u_int8_t *a_item;
+    if (!PyArg_ParseTuple(args, "O|b", &in_obj, &a_item))
+        return NULL;
+    dap_chain_datum_tx_t **txs = PyListToDapChainDatumTxArray(in_obj);
+    int res = dap_chain_datum_tx_add_item(txs, a_item);
+    if (res == -1){
+        return NULL;
+    } else {
+        PyObject *out = DapChainDatumTxArrayToPyList(txs);
+        return Py_BuildValue("O", out);
+    }
+}
+PyObject *dap_chain_datum_tx_add_in_item_py(PyObject *self, PyObject *args){
+    PyObject *in_obj_datum_txs;
+    PyObject *in_obj_hash_fast;
+    uint32_t in_tx_out_pref_idx;
+    if (!PyArg_ParseTuple(args, "O|O|I", &in_obj_datum_txs, &in_obj_hash_fast, &in_tx_out_pref_idx))
+        return NULL;
+    dap_chain_datum_tx_t **a_txs = PyListToDapChainDatumTxArray(in_obj_datum_txs);
+    int res = dap_chain_datum_tx_add_in_item(a_txs, ((PyDapChainHashFastObject*)in_obj_hash_fast)->hash_fast,
+                                             in_tx_out_pref_idx);
+    if (res == -1){
+        return NULL;
+    } else {
+        PyObject *out = DapChainDatumTxArrayToPyList(a_txs);
+        return Py_BuildValue("O", out);
+    }
+}
+
+PyObject *dap_chain_datum_tx_add_in_cond_item_py(PyObject *self, PyObject *args){
+    PyObject *in_obj_datum_txs;
+    PyObject *in_chain_hash_fast;
+    unsigned int in_tx_out_prev_idx;
+    unsigned int in_receipt_idx;
+    if (!PyArg_ParseTuple(args, "O|O|I|I", &in_obj_datum_txs, &in_chain_hash_fast, &in_tx_out_prev_idx, &in_receipt_idx))
+        return NULL;
+    dap_chain_datum_tx_t **a_txs = PyListToDapChainDatumTxArray(in_obj_datum_txs);
+    int res = dap_chain_datum_tx_add_in_cond_item(a_txs, ((PyDapChainHashFastObject*)in_chain_hash_fast)->hash_fast, in_tx_out_prev_idx, in_receipt_idx);
+    return PyLong_FromLong(res);
+}
+
+PyObject *dap_chain_datum_tx_add_out_item_py(PyObject *self, PyObject *args){
+    PyObject *in_obj_datum_txs;
+    PyObject *in_addr;
+    uint64_t value;
+    if (!PyArg_ParseTuple(args, "O|O|k", &in_obj_datum_txs, &in_addr, value))
+        return NULL;
+    dap_chain_datum_tx_t **txs = PyListToDapChainDatumTxArray(in_obj_datum_txs);
+    int res = dap_chain_datum_tx_add_out_item(txs, ((PyDapChainAddrObject*)in_addr)->addr, value);
+    if (res == -1){
+        return NULL;
+    } else {
+        PyObject *out = DapChainDatumTxArrayToPyList(txs);
+        return Py_BuildValue("O", out);
+    }
+}
+PyObject *dap_chain_datum_tx_add_out_cond_item_py(PyObject *self, PyObject *args){
+    PyObject *obj_txs;
+    PyObject *obj_key;
+    PyObject *obj_srv_uid;
+    uint64_t value;
+    uint64_t value_max_per_unit;
+    PyObject *obj_srv_price_unit_uid;
+    PyObject *obj_cond_bytes;
+    Py_ssize_t cond_size;
+    if (!PyArg_ParseTuple(args, "O|O|O|k|k|O|O|n", &obj_txs, &obj_key, &obj_srv_uid, &value, &value_max_per_unit,
+                          &obj_srv_price_unit_uid, &obj_cond_bytes, &cond_size))
+        return NULL;
+    dap_chain_datum_tx_t **txs = PyListToDapChainDatumTxArray(obj_txs);
+    void *cond = (void*)PyBytes_AsString(obj_cond_bytes);
+    int res = dap_chain_datum_tx_add_out_cond_item(txs, ((PyCryptoKeyObject*)obj_key)->key, ((PyDapChainNetSrvUIDObject*)obj_srv_uid)->net_srv_uid,
+                                                   value, value_max_per_unit, ((PyDapChainNetSrvPriceUnitUIDObject*)obj_srv_price_unit_uid)->price_unit_uid,
+                                                   cond, (size_t)cond_size);
+    if (res == -1){
+        return NULL;
+    } else {
+        PyObject *out = DapChainDatumTxArrayToPyList(txs);
+        return Py_BuildValue("O", out);
+    }
+}
+PyObject *dap_chain_datum_tx_add_sign_item_py(PyObject *self, PyObject *args){
+    PyObject *obj_txs;
+    PyObject *obj_key;
+    if (!PyArg_ParseTuple(args, "O|O", &obj_txs, &obj_key))
+        return NULL;
+    dap_chain_datum_tx_t **txs = PyListToDapChainDatumTxArray(obj_txs);
+    int res = dap_chain_datum_tx_add_sign_item(txs, ((PyCryptoKeyObject*)obj_key)->key);
+    if (res == -1){
+        return NULL;
+    } else {
+        PyObject *out = DapChainDatumTxArrayToPyList(txs);
+        return Py_BuildValue("O", out);
+    }
+}
+PyObject *dap_chain_datum_tx_verify_sign_py(PyObject *self, PyObject *args){
+    int res = dap_chain_datum_tx_verify_sign(((PyDapChainDatumTxObject*)self)->datum_tx);
+    return PyLong_FromLong(res);
+}
+
+static dap_chain_datum_tx_t **PyListToDapChainDatumTxArray(PyObject *a_in_obj){
+    Py_ssize_t size = PyList_Size(a_in_obj);
+    dap_chain_datum_tx_t **txs = calloc(sizeof(dap_chain_datum_tx_t), (size_t)size);
+    for (Py_ssize_t i = 0; i < size;i++){
+        txs[i] = ((PyDapChainDatumTxObject*)PyList_GetItem(a_in_obj, i))->datum_tx;
+    }
+    return txs;
+}
+
+static PyObject* DapChainDatumTxArrayToPyList(dap_chain_datum_tx_t** datum_txs){
+    size_t len = sizeof(datum_txs) / sizeof(datum_txs[0]);
+    PyObject* list = PyList_New((Py_ssize_t)len);
+    for (size_t i=0; i < len; i++){
+        PyObject *obj = _PyObject_New(&DapChainDatumTx_DapChainDatumTxObjectType);
+        ((PyDapChainDatumTxObject*)obj)->datum_tx = datum_txs[i];
+        PyList_Append(list, obj);
+    }
+    return list;
+}
+
+dap_chain_tx_out_cond_t **PyListToDapChainTxOutCond(PyObject *list){
+    Py_ssize_t size = PyList_Size(list);
+    dap_chain_tx_out_cond_t **out_conds = calloc(sizeof(dap_chain_tx_out_cond_t), (size_t)size);
+    for (Py_ssize_t i=0; i < size; i++){
+        out_conds[i] = ((PyDapChainTxOutCondObject*)PyList_GetItem(list, i))->out_cond;
+    }
+    return out_conds;
+}
+
+PyObject *DapChainTxOutCondObjectToPyList(dap_chain_tx_out_cond_t **out_cond){
+    size_t len = sizeof(out_cond) / sizeof(out_cond[0]);
+    PyObject *list = PyList_New((Py_ssize_t)len);
+    for (size_t i=0; i< len;i++ ){
+        PyObject *obj = _PyObject_New(&DapChainTxOutCond_DapChainTxOutCondObjectType);
+        ((PyDapChainTxOutCondObject*)obj)->out_cond = out_cond[i];
+        PyList_Append(list, obj);
+    }
+    return list;
+}
+
+/* -------------------------------------- */
-- 
GitLab