mitum-py-util introduces the use of mitum-currency, mitum-document, and mitum-currency-extension for python.
All addresses and keys in the document are examples. Please use your exact address and key when you actually use this package. All values in this document are not reliable.
For all examples in this document, we are not responsible for using incorrect values.
Recommended requirements for 'mitum-py-util' are as follows:
- python v3.9 or later.
$ python --version
Python 3.9.2
$ git clone https://github.com/ProtoconNet/mitum-py-util.git
$ cd mitum-py-util
$ python setup.py install
If setup.py
is not working properly, use requirements.txt
to install the required package before running setup.py
.
$ cd mitum-py-util
$ pip install -r requirements.txt
Class |
---|
Generator |
JSONParser |
Signer |
Appendix |
---|
About Time Stamp |
There is a type suffix for each key and address.
private key -> mpr
public key -> mpu
address -> mca
A new keypair can be obtained through getNewKeypair
. You can also import keypairs from a known private key or seed.
getNewKeypair()
getKeypairFromPrivateKey(key)
getKeypairFromSeed(seed)
from mitumc.key import getNewKeypair, getKeypairFromPrivateKey, getKeypairFromSeed
# get new Keypair
kp = getNewKeypair() # returns BTCKeyPair
kp.privateKey # KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr
kp.publicKey # 24TbbrNYVngpPEdq6Zc5rD1PQSTGQpqwabB9nVmmonXjqmpu
# get Keypair from your private key
pkp = getKeypairFromPrivateKey("L2ddEkdgYVBkhtdN8HVXLZk5eAcdqXxecd17FDTobVeFfZNPk2ZDmpr")
# get Keypair from your seed
skp = getKeypairFromSeed("Thisisaseedforthisexample.len(seed)>=36.")
String seeds must be longer than or equal to 36.
This section describes how to use the Generator
and what you need to prepare to use it.
mitum-py-util provides three operations of mitum-currency.
- create-accounts creates accounts corresponding to public keys with pre-registered accounts.
- key-updater updates the public keys in your account to something else.
- transfers transfers tokens from an account to another account.
mitum-currency supports many types of operations, but the mitum-py-util only provides frequently used operations.
In addition, mitum-py-util provides two operations of mitum-document.
- create-documents creates documents.
- update-documents updates the state of the document.
Currently, the SDK supports two models, blocksign and blockcity, which are implemented based on mitum-document.
mitum-blocksign provides an additional operation called sign-documents.
The following document types are available for each model:
- Use only one document type named
blocksign
for mitum blocksign. - There are four document types for blockcity:
user
,land
,vote
andhistory
.
The mitumc package provides a Generator
class for creating jobs.
- Set the
network id
of theGenerator
.
from mitumc import Generator
id = 'mitum'
generator = Generator(id)
- For mitum-currency, use
Generator.currency
.
from mitumc import Generator
generator = Generator('mitum')
currencyGenerator = generator.currency
Generator.currency
supports:
Generator.currency.key(key, weight) # 1 <= $weight <= 100
Generator.currency.amount(currencyId, amount)
Generator.currency.keys(keys, threshold) # 1 <= $threshold <= 100
Generator.currency.amounts(amounts)
Generator.currency.getCreateAccountsItem(keys, amounts)
Generator.currency.getTransfersItem(receiver, amounts)
Generator.currency.getCreateAccountsFact(sender, items)
Generator.currency.getKeyUpdaterFact(target, currencyId, keys)
Generator.currency.getTransfersFact(sender, items)
Generator.currency.extension.getCreateContractAccountsItem(keys, amounts)
Generator.currency.extension.getWithdrawsItem(target, amounts)
Generator.currency.extension.getCreateContractAccountsFact(sender, items)
Generator.currency.extension.getWithdrawsFact(sender, items)
- For mitum-document, use
Generator.document
.
from mitumc import Generator
generator = Generator('mitum')
documentGenerator = generator.document
Generator.document
supports:
Generator.document.getCreateDocumentsItem(document, currencyId)
Generator.document.getUpdateDocumentsItem(document, currencyId)
Generator.document.getCreateDocumentsFact(sender, items)
Generator.document.getUpdateDocumentsFact(sender, items)
Note that create-documents and update-documents in the mitum-document are common tasks for blocksign and blockcity.
The document helps you create items and facts for these operations.
- To generate objects specific to blocksign, use
Generator.document.blocksign
.
Generator.document.blocksign.user(address, signcode, signed)
Generator.document.blocksign.document(documentId, owner, fileHash, creator, title, size, signers)
Generator.document.blocksign.getSignDocumentsItem(documentId, owner, currencyId)
Generator.document.blocksign.getSignDocumentsFact(sender, items)
sign-documents is provided only for blocksign.
Therefore, it is Generator.document.blocksign
rather than Generator.document
that supports sign-documents.
The output of user(...)
is provided as signer
of creator
or document
.
- To generate objects specific to blockcity, use
Generator.document.blockcity
.
Generator.document.blockcity.candidate(address, nickname, manifest, count)
Generator.document.blockcity.userStatistics(hp, strength, agility, dexterity, charisma intelligence, vital)
Generator.document.blockcity.userDocument(documentId, owner, gold, bankGold, userStatistics)
Generator.document.blockcity.landDocument(documentId, owner, address, area, renter, account, rentDate, period)
Generator.document.blockcity.voteDocument(documentId, owner, round, endTime, candidates, bossName, account, office)
Generator.document.blockcity.historyDocument(documentId, owner, name, account, date, usage, application)
- For mitum-feefi, use
Generator.feefi
.
Generator.feefi.getPoolRegisterFact(sender, target, initFee, incomeCid, outgoCid, cid)
Generator.feefi.getPoolPolicyUpdaterFact(sender, target, fee, incomeCid, outgoCid, cid)
Generator.feefi.getPoolDepositsFact(sender, pool, incomeCid, outgoCid, amount)
Generator.feefi.getPoolWithdrawFact(sender, pool, incomeCid, outgoCid, amounts)
- For mitum-nft, use
Generator.nft
.
Generator.nft.signer(account, share, signed)
Generator.nft.signers(total, _signers)
Generator.nft.collectionRegisterForm(target, symbol, name, royalty, uri, whites)
Generator.nft.collectionPolicy(name, royalty, uri, whites)
Generator.nft.mintForm(hash, uri, creators, copyrighters)
Generator.nft.getMintItem(collection, form, cid)
Generator.nft.getTransferItem(receiver, nid, cid)
Generator.nft.getBurnItem(nid, cid)
Generator.nft.getApproveItem(approved, nid, cid)
Generator.nft.getDelegateItem(collection, agent, mode, cid) # mode: ["allow" || "cancel"]
Generator.nft.getSignItem(qualification, nid, cid) # qualification: ["creator" || "copyrighter"]
Generator.nft.getCollectionRegisgerFact(sender, form, cid)
Generator.nft.getCollectioPolicyUpdaterFact(sender, collection, policy, cid)
Generator.nft.getMintFact(sender, items)
Generator.nft.getTransferFact(sender, items)
Generator.nft.getBurnFact(sender, items)
Generator.nft.getApproveFact(sender, items)
Generator.nft.getDelegateFact(sender, items)
Generator.nft.getSignFact(sender, items)
- To create
Operation
andSeal
, useGenerator.getOperation(fact, memo)
andGenerator.getSeal(signKey, operations)
.
Generator.getOperation(fact, memo)
Generator.getSeal(signKey, operations)
Use cases of Generator
can be found in the next part.
You can calculate the address of the account with the key.
In mitum, account
consists of threshold
and (key, weight) pairs
.
The available range for each value is 1 <= threshold, weight <= 100
.
The sum of all weights in the account must be greater than or equal to the threshold.
To obtain an address, use mitumc.Generator.currency
.
from mitumc import Generator
gn = Generator('mitum').currency
pub1 = "21nHZiHxhjwXtXXhPFzMvGyAAdCobmZeCC1bT1yLXAaw2mpu"
pub2 = "mZKEkm4BnFq6ynq98q4bCEcE4kZhzLSViPbCx8LDBXk2mpu"
pub3 = "dPBms4cH4t8tiH6uNbq37HrEWwgrrEZqHQwSbvqEBJ85mpu"
key1 = gn.key(pub1, 40)
key2 = gn.key(pub2, 40)
key3 = gn.key(pub3, 40)
keys = gn.keys([key1, key2, key3], 80)
address = keys.address # your address
In this example, because the sum of the weights of the two keys is greater than or equal to the account threshold, you can sign the operations with only two keys.
This part shows how to create an operation for mitum-currency.
For new accounts, public keys
and initial amounts
must be set. You can use the source account to create and register a new account that consists of target public keys.
However, the source account must already be registered.
When using Generator
, you must first set the network id
.
from mitumc import Generator
srcPriv = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"
srcAddr = "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca"
targetPub = "2177RF13ZZXpdE1wf7wu5f9CHKaA2zSyLW5dk18ExyJ84mpu"
generator = Generator('mitum')
gn = generator.currency
key = gn.key(targetPub, 100)
keys = gn.keys([key], 100)
amount = gn.amount('MCC', 100)
amounts = gn.amounts([amount])
createAccountsItem = gn.getCreateAccountsItem(keys, amounts)
createAccountsFact = gn.getCreateAccountsFact(srcAddr, [createAccountsItem])
createAccounts = generator.getOperation(createAccountsFact, "")
createAccounts.addFactSign(srcPriv)
You must add new fact signature by addFactSign()
before creating seal or json files from an operation.
Then Operation.dict()
and Operation.json(file_name)
methods work correctly.
Operation.dict()
Operation.json("create_account.json")
Then the output format is the same as this. (Each value depends on the input argument and time.)
key-updater literally support updating public keys to something else.
from mitumc import Generator
srcPriv = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"
srcAddr = "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca"
desPub = "2BqW3iy3bb9Z1fS21opL3z4da69K25d9zR5DM2CnSuNYxmpu"
generator = Generator('mitum')
gn = generator.currency
key = gn.key(desPub, 100)
keys = gn.keys([key], 100)
keyUpdaterFact = gn.getKeyUpdaterFact(srcAddr, keys, "MCC")
keyUpdater = generator.getOperation(keyUpdaterFact, "")
keyUpdater.addFactSign(srcPriv)
To cerate an operation, you must prepare a target address, not a public key. transfers supports sending tokens to other accounts.
from mitumc import Generator
srcPriv = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"
srcAddr = "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca"
desAddr = "D2KjoTG6yhE64jGQu7y2hUYPzRoJ2RDcnPsWrtLBDaPTmca"
generator = Generator('mitum')
gn = generator.currency
amount = gn.amount('MCC', 100)
amounts = gn.getAmounts([amount])
transfersItem = gn.getTransfersItem(desAddr, amounts)
transfersFact = gn.getTransfersFact(srcAddr, [transfersItem])
transfers = generator.getOperation(transfersFact, "")
transfers.addFactSign(srcPriv)
For new contract accounts, public keys
and initial amounts
must be set. You can use the source account to create and register a new account that consists of target public keys. The owner of the new contract account will be this source account.
Note that source account must be already registered one.
from mitumc import Generator
srcPriv = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"
srcAddr = "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca"
targetPub = "2177RF13ZZXpdE1wf7wu5f9CHKaA2zSyLW5dk18ExyJ84mpu"
generator = Generator('mitum')
gn = generator.currency
key = gn.key(targetPub, 100)
keys = gn.keys([key], 100)
amount = gn.amount('MCC', 100)
amounts = gn.amounts([amount])
createContractAccountsItem = gn.extension.getCreateContractAccountsItem(keys, amounts)
createContractAccountsFact = gn.extension.getCreateContractAccountsFact(srcAddr, [createContractAccountsItem])
createContractAccounts = generator.getOperation(createContractAccountsFact, "")
createContractAccounts.addFactSign(srcPriv)
To create an operation, you must prepare the target contract account address. withdraws supports withdrawal of tokens from contract accounts.
from mitumc import Generator
srcPriv = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"
srcAddr = "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca"
desAddr = "D2KjoTG6yhE64jGQu7y2hUYPzRoJ2RDcnPsWrtLBDaPTmca"
generator = Generator('mitum')
gn = generator.currency
amount = gn.amount('MCC', 100)
amounts = gn.getAmounts([amount])
withdrawsItem = gn.extension.getWithdrawsItem(desAddr, amounts)
withdrawsFact = gn.extension.getWithdrawsFact(srcAddr, [transfersItem])
withdraws = generator.getOperation(withdrawsFact, "")
withdraws.addFactSign(srcPriv)
To create or update documents, you must prepare an available document object for each operation item.
For example, blocksign supports one type of document with a hint called mitum-blocksign-document-data
.
However, blockcity supports four types of documents: user/land/vote/history documents that use different hints than blocksign.
In other words, you must create a document that corresponds to the type of document you want.
First, we'll show you how to create documents by type.
As mentioned above, blocksign only uses documents of blocksign type.
You must first prepare the creator
and the signer
.
Each is called a user
for convenience.
You can create a user
using Generator.document.blocksign.user(address, signCode, signed)
.
Here's what you need to prepare to create a document:
- document id
- owner
- file hash
- creator - from
user
- title
- file size
- a signer list - signers from
user
All document id
s in the blocksign are followed by the suffix sdi
.
from mitumc import Generator
user1 = "FB3m9zS9DWYLgRETYr5j5A8WCTk5QY6dHAjTpzkjyPvzmca"
user2 = "D2KjoTG6yhE64jGQu7y2hUYPzRoJ2RDcnPsWrtLBDaPTmca"
gn = Generator('mitum').document.blocksign
creator = gn.user(user1, "signer01", True)
signer1 = gn.user(user1, "signer01", True)
signer2 = gn.user(user2, "signer02", False)
document = gn.document("bstest01sdi", user1, "fs:01", creator, "doc01", "1234", [signer1, signer2])
For more information about each argument in the example, see Generator.
The following document types are supported in blockcity:
- User Data
- Land Data
- Voting Data
- History Data
The document id
for each document type has a unique suffix.
- user data:
cui
- land data:
cli
- vote data:
cvi
- history data:
chi
The documents are used only in blockcity.
For more information about each argument in the example, see Generator.
Before you create a user
document, you must prepare the following:
- document id
- Each value in a user statistics
- document owner
- user's gold and bank gold
from mitumc import Generator
gn = Generator('mitum').document.blockcity
statistics = gn.userStatistics(1, 1, 1, 1, 1, 1, 1)
document = gn.userDocument("4cui", "5KGBDDsmNXCa69kVAgRxDovu7JWxdsUxtAz7GncKxRfqmca", 10, 10, statistics)
Here's what you need to prepare.
- document id
- document owner
- address to rent
- area to rent
- renter who rent
- account who rent
- rent date and period
from mitumc import Generator
gn = Generator('mitum').document.blockcity
document = gn.landDocument("4cli", "5KGBDDsmNXCa69kVAgRxDovu7JWxdsUxtAz7GncKxRfqmca", "abcd", "city1", "foo", "Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca", "2021-10-22", 10)
Here's what you need to prepare.
- voting round
- end time of voting
- candidates - address, manifest, nickname and count
- boss name
- account address
- termofoffice
from mitumc import Generator
gn = Generator('mitum').document.blockcity
c1 = gn.candidate("8sXvbEaGh1vfpSWSib7qiJQQeqxVJ5YQRPpceaa5rd9Ymca", "foo1", "", 1)
c2 = gn.candidate("Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca", "foo2", "", 2)
document = gn.voteDocument("4cvi", "5KGBDDsmNXCa69kVAgRxDovu7JWxdsUxtAz7GncKxRfqmca", 1, "2022-02-22", [c1, c2], "foo", "Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca", "2022")
Here's what you need to prepare.
- document id
- document owner
- name
- account
- date
- usage
- application
from mitumc import Generator
gn = Generator('mitum').document.blockcity
document = gn.historyDocument("4chi", "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca", "abcd", "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca", "2022-02-01T00:00:00.000+09:00", "bob", "foo")
All models based on mitum-document use operation as create-documents and update-documents by default.
This section will show you how to create documents and update documents for documents created in the previous part.
Go to the previous part for document creation.
To create a create-documents operation, you must prepare the following:
- currency id for fees
- document
- sender's address and private key
from mitumc import Generator
generator = Generator('mitum')
gn = generator.document
# .. generate document
item = gn.getCreateDocumentsItem(document, "PEN")
fact = gn.getCreateDocumentsFact("5KGBDDsmNXCa69kVAgRxDovu7JWxdsUxtAz7GncKxRfqmca", [item])
oper = generator.getOperation(fact, "")
oper.addFactSign("Kz5gif6kskQA8HD6GeEjPse1LuqF8d3WFEauTSAuCwD1h94vboyAmpr")
For Document
, see the beginning of Generate Document Operations.
For more information, see Generator.
To create a update-documents operation, you must prepare the following:
- currency id for fees
- document
- sender's address and private key
from mitumc import Generator
generator = Generator('mitum')
gn = generator.document
# .. generate document
item = gn.getUpdateDocumentsItem(document, "PEN")
fact = gn.getUpdateDocumentsFact("5KGBDDsmNXCa69kVAgRxDovu7JWxdsUxtAz7GncKxRfqmca", [item])
oper = generator.getOperation(fact, "")
oper.addFactSign("Kz5gif6kskQA8HD6GeEjPse1LuqF8d3WFEauTSAuCwD1h94vboyAmpr")
For Document
, see the beginning of Generate Document Operations.
For more information, see Generator.
As mentioned above, the sign-documents operation is used only for blocksign.
Therefore, you must use the generator, Generator.document.blocksign
, specific to blocksign, to create items and facts for sign-documents.
To create an item for the sign-document, you must prepare the following:
- document id
- owner's address
- currency id for fee
You do not need to prepare a document for sign-document. Only document id
is required.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
item = gn.document.blocksign.getSignDocumentsItem("4000sdi", "5KGBDDsmNXCa69kVAgRxDovu7JWxdsUxtAz7GncKxRfqmca", "PEN")
fact = gn.document.blocksign.getSignDocumentsFact("Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca", [item])
operation = gn.getOperation(fact, "")
operation.addSign("Kz5gif6kskQA8HD6GeEjPse1LuqF8d3WFEauTSAuCwD1h94vboyAmpr")
See Generator for details.
This part shows how to generate operations for mitum-feefi.
pool-register supports registering pool
in a contract account.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
fact = gn.feefi.getPoolRegisterFact("CkiVJAwUhnhUWmPJcFCJrFSM7Y6jjLCdPMu2smEic2dTmca", "4rRNULRfGFLPTfZrhFzGqvbQ2cweiJuEZFNqrsMA353hmca", 100, "PEN", "AAA", "MCC")
operation = gn.getOperation(fact, "")
operation.addFactSign("KxE8Mq8TFfaDZ3d68uQmYKALhzFuZYGGb2UjwjtCsrhB7eSRmtnompr")
pool-policy-updater supports updating registered pool policies.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
fact = gn.feefi.getPoolPolicyUpdaterFact("CkiVJAwUhnhUWmPJcFCJrFSM7Y6jjLCdPMu2smEic2dTmca", "4rRNULRfGFLPTfZrhFzGqvbQ2cweiJuEZFNqrsMA353hmca", 100, "PEN", "AAA", "MCC")
operation = gn.getOperation(fact, "")
operation.addFactSign("KxE8Mq8TFfaDZ3d68uQmYKALhzFuZYGGb2UjwjtCsrhB7eSRmtnompr")
pool-deposits supports depositing amounts into the pool.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
fact = gn.feefi.getPoolDepositsFact("CkiVJAwUhnhUWmPJcFCJrFSM7Y6jjLCdPMu2smEic2dTmca", "4rRNULRfGFLPTfZrhFzGqvbQ2cweiJuEZFNqrsMA353hmca", "PEN", "AAA", 100)
operation = gn.getOperation(fact, "")
operationaddFactSign("KxE8Mq8TFfaDZ3d68uQmYKALhzFuZYGGb2UjwjtCsrhB7eSRmtnompr")
pool-withdraw supports withdrawing amounts from the pool.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
amounts = gn.currency.amounts([gn.currency.amount("PEN", 1)])
fact = gn.feefi.getPoolWithdrawFact("CkiVJAwUhnhUWmPJcFCJrFSM7Y6jjLCdPMu2smEic2dTmca", "4rRNULRfGFLPTfZrhFzGqvbQ2cweiJuEZFNqrsMA353hmca", "PEN", "AAA", amounts)
operation = gn.getOperation(fact, "")
operation.addFactSign("KxE8Mq8TFfaDZ3d68uQmYKALhzFuZYGGb2UjwjtCsrhB7eSRmtnompr")
This part shows how to generate operations for mitum-nft.
collection-register supports the registration of collection
in the contract account.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
form = gn.nft.collectionRegisterForm("4rRNULRfGFLPTfZrhFzGqvbQ2cweiJuEZFNqrsMA353hmca", "FSTCOL", "First Collection", 1, "https://localhost:5000/collection/FSTCOL", ["9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca"])
fact = gn.nft.getCollectionRegisgerFact("9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca", form, "MCC")
operation = gn.getOperation(fact, "")
opoperation.addFactSign("KxzpnyJ1PEfQ53aFhdEEUAxgzad3n9NHFgsByvcWYfsbaHtv3gPLmpr")
collection-policy-updater supports updating collection policies.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
policy = gn.nft.collectionPolicy("Updated Collection", 2, "https://localhost:5000/collection/FSTCOL", ["9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca"])
fact = gn.nft.getCollectioPolicyUpdaterFact("9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca", "FSTCOL", policy, "MCC")
operation = gn.getOperation(fact, "")
operation.addFactSign("KxzpnyJ1PEfQ53aFhdEEUAxgzad3n9NHFgsByvcWYfsbaHtv3gPLmpr")
mint supports the registration of a new nft in the collection.
This example shows how to create an operation when both the creator and copyrighter are the same account as minting nft. Actually, any general account can be a creator and a copyrighter.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
creator1 = gn.nft.signer("5deA8UKm3bZoHSoua3JGuZWMAniUA4TybLHyWnvnFoYPmca", 50, False)
creator2 = gn.nft.signer("9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca", 50, False)
creators = gn.nft.signers(100, [creator1, creator2])
copyrighter1 = gn.nft.signer("5deA8UKm3bZoHSoua3JGuZWMAniUA4TybLHyWnvnFoYPmca", 100, False)
copyrighters = gn.nft.signers(100, [copyrighter1])
form = gn.nft.mintForm("fill nft hash here", "https://localhost:5000/FSTCOL/1", creators, copyrighters)
item = gn.nft.getMintItem("FSTCOL", form, "MCC")
fact = gn.nft.getMintFact("9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca", [item])
operation = gn.getOperation(fact, "")
operation.addFactSign("KxzpnyJ1PEfQ53aFhdEEUAxgzad3n9NHFgsByvcWYfsbaHtv3gPLmpr")
transfer supports the transfer of nft.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
item = gn.nft.getTransferItem("5deA8UKm3bZoHSoua3JGuZWMAniUA4TybLHyWnvnFoYPmca", "FSTCOL-00001", "MCC")
fact = gn.nft.getTransferFact("9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca", [item])
operation = gn.getOperation(fact, "")
operation.addFactSign("KxzpnyJ1PEfQ53aFhdEEUAxgzad3n9NHFgsByvcWYfsbaHtv3gPLmpr")
burn supports nft burning.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
item = gn.nft.getBurnItem("FSTCOL-00001", "MCC")
fact = gn.nft.getBurnFact("5deA8UKm3bZoHSoua3JGuZWMAniUA4TybLHyWnvnFoYPmca", [item])
operation = gn.getOperation(fact, "")
operation.addFactSign("KydyTuc5kstBSWD3RzXLbuyZ9PyLi4EWAT6BwWx7MruBsmKPUW8zmpr")
approve supports delegation of authority for specific nft ownership changes.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
item = gn.nft.getApproveItem("9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca", "FSTCOL-00001", "MCC")
fact = gn.nft.getApproveFact("5deA8UKm3bZoHSoua3JGuZWMAniUA4TybLHyWnvnFoYPmca", [item])
operation = gn.getOperation(fact, "")
operation.addFactSign("KydyTuc5kstBSWD3RzXLbuyZ9PyLi4EWAT6BwWx7MruBsmKPUW8zmpr")
delegation supports delegating the authority to change ownership of all nfts held by one general account for a collection.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
item = gn.nft.getDelegateItem("FSTCOL", "5deA8UKm3bZoHSoua3JGuZWMAniUA4TybLHyWnvnFoYPmca", "allow", "MCC")
fact = gn.nft.getDelegateFact("9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca", [item])
operation = gn.getOperation(fact, "")
operation.addFactSign("KxzpnyJ1PEfQ53aFhdEEUAxgzad3n9NHFgsByvcWYfsbaHtv3gPLmpr")
sign supports signing in nft as a creator or copyrighter.
from mitumc import Generator
gn = Generator('mitum') # Generator({networkId})
item = gn.nft.getSignItem("creator", "FSTCOL-00001", "MCC")
fact = gn.nft.getSignFact("9MBW3xRBbkPSa5JVv2kMgnsXvGj9scSupZcSZ99cNPbwmca", [item])
operation = gn.getOperation(fact, "")
operation.addFactSign("KxzpnyJ1PEfQ53aFhdEEUAxgzad3n9NHFgsByvcWYfsbaHtv3gPLmpr")
You can create a json file for a seal
that consists of multiple operations. Any type of operation provided by mitum-py-util is available.
To create a seal
, mitum-py-util requires the following:
signing key
a list of pre-constructed operations
which is not empty
The signature key(private key generated by mitum) does not need to be registered.
Even without the JSONParser
class provided by mitumc
, you can create a json file of seal
objects created through a package embedded in javascript. However, for convenience, I recommend using JSONParser
.
The modules supported by JSONParser
are as follows:
JSONParser.toString(seal)
JSONParser.toFile(seal, fName)
The next part introduces the use cases of JSONParser
.
Let's first assume that all operations are jobs created by the Generator
.
from mitumc import Generator, JSONParser
generator = Generator('mitum')
... omitted
''' Create each operation [createAccounts, keyUpdater, transfers] with generator. See above sections.
'''
...
signKey = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"
operations = [createAccounts, keyUpdater, transfers]
seal = generator.getSeal(signKey, operations)
JSONParser.toString(seal)
JSONParser.toFile(seal, 'seal.json')
The output format of JSONParser.toFile(...)
is the same as this.
Use curl
to send operations and seals to the network.
~$ curl -X POST -H "Content-Type: application/json" -d @seal.json https://{mitum network address}/builder/send
seal.json
becomes your seal json file.
Sign the message with a mitum keypair.
mitumc.key
module supports keypair generation and import. You can obtain signature digest by signing with a keypair.
Each keypair supports the sign
method, which generates a byte-type signature by signing a byte-type message.
To obtain a signature for mitum, encode the signature using base58
.
from mitumc.key import getNewKeypair
import base58
msg = b'mitum'
kp = getNewKeypair()
signature = kp.sign(msg) # b'0E\x02!\x00\xd4\xcb\xa3\x05\xec\x92-\xde\xcc\xb9;,\xf7k\x0bl\x8d\xf7@B\xaf\xf6 \x0f\xa5\xd1\x10]N1\xcc<\x02 \x119; lJ\x83\x1e\xdd\xfd\xce\x12vVK\x8aG\xae\xba\xe7\x03%\x98\xa5\x1b\'\x99"\xc2\xaf\xa5c'
mitumSignature = base58.b58encode(sign).decode() # AN1rKvtXAEWjt4KUGZxoZ8e8YMVuLPo6MqciW9En5DbA1w1FLp6NhGmMFCuAjVipRBibWDkiVLQYvp4PcTiVezqNv4GtUKx18
WYou can add a new fact signature to operation json using the Signer
object in mitum-py-util.
To add a signature, you must prepare a network id
and a signature key
.
For example, suppose you have an operation json file that has already been implemented, as shown below.
operation.json
{
"memo": "",
"_hint": "mitum-currency-transfers-operation-v0.0.1",
"fact": {
"_hint": "mitum-currency-transfers-operation-fact-v0.0.1",
"hash": "DDQ1pjXsPVoGV5iWRZN4RhKSJ9zZRzn21tXW6HdM1gEe",
"token": "MjAyMS0xMi0yOFQwNDo0MzowMy4xNzY5ODIrMDA6MDA=",
"sender": "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca",
"items": [{
"_hint": "mitum-currency-transfers-item-single-amount-v0.0.1",
"receiver": "D2KjoTG6yhE64jGQu7y2hUYPzRoJ2RDcnPsWrtLBDaPTmca",
"amounts": [{
"_hint": "mitum-currency-amount-v0.0.1",
"amount": "100",
"currency": "MCC"
}]
}]
},
"hash": "3Eu7dyVpKtnYVf2HurNjoHLRPe9znQR2xWEkFGFTq1F8",
"fact_signs": [{
"_hint": "base-fact-sign-v0.0.1",
"signer": "wAYCFysPp8bXP8YnnDJNjJGQbj6m9cvnqQUGkchMC1xfmpu",
"signature": "AN1rKvtWVjsrSuZvYpyqmCEjL5YXSw4P4jXMBbANHHmX1HY7ukw1dazdpFZTjAnhFBzt9Xq3woJHf5DCPTUGiA96LSvGBP4vz",
"signed_at": "2021-12-28T04:43:03.190259Z"
}]
}
Use Signer.signOperation(filePath)
to add a new fact signature to the fact_signs
array.
The operation hash changes after adding a fact signature.
from mitumc import Signer, JSONParser
signer = Signer('mitum', 'L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr')
signed = signer.signOperation('operation.json')
JSONParser.toFile(signed, 'signed.json')
After signing, the above operation must be changed as follows.
{
"memo": "",
"_hint": "mitum-currency-transfers-operation-v0.0.1",
"fact": {
"_hint": "mitum-currency-transfers-operation-fact-v0.0.1",
"hash": "DDQ1pjXsPVoGV5iWRZN4RhKSJ9zZRzn21tXW6HdM1gEe",
"token": "MjAyMS0xMi0yOFQwNDo0MzowMy4xNzY5ODIrMDA6MDA=",
"sender": "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca",
"items": [
{
"_hint": "mitum-currency-transfers-item-single-amount-v0.0.1",
"receiver": "D2KjoTG6yhE64jGQu7y2hUYPzRoJ2RDcnPsWrtLBDaPTmca",
"amounts": [
{
"_hint": "mitum-currency-amount-v0.0.1",
"amount": "100",
"currency": "MCC"
}
]
}
]
},
"fact_signs": [
{
"_hint": "base-fact-sign-v0.0.1",
"signer": "wAYCFysPp8bXP8YnnDJNjJGQbj6m9cvnqQUGkchMC1xfmpu",
"signature": "AN1rKvtWVjsrSuZvYpyqmCEjL5YXSw4P4jXMBbANHHmX1HY7ukw1dazdpFZTjAnhFBzt9Xq3woJHf5DCPTUGiA96LSvGBP4vz",
"signed_at": "2021-12-28T04:43:03.190259Z"
},
{
"_hint": "base-fact-sign-v0.0.1",
"signer": "wAYCFysPp8bXP8YnnDJNjJGQbj6m9cvnqQUGkchMC1xfmpu",
"signature": "381yXYrVVevf9tqV2cTBAiKQYoGSm4tn5ZGsHB5U1nX7xxKGkW9qMiDhz7P5aLhAbif1bn7hehydHeWishoY8rTQP1Ze7xr9",
"signed_at": "2021-12-28T07:33:06.475723Z"
}
],
"hash": "CAjj7KhVhwPbHToHQ1JFkP9DoBjYU9qq91Dq3XkLtvVe"
}
Signer
class returns a dictionary object.
mitum.hash
supports sha256
and sha3
hashing.
from mitumc.hash import sha256, sha3
msg = b'mitum'
sha2_hash = sha256(msg)
sha3_hash = sha3(msg)
print(sha2_hash.digest)
print(sha2_hash.hash)
print(sha3_hash.digest)
print(sha3_hash.hash)
The results are as follows:
$ python mitumc_hash.py
b'\xf7.\xd28\xfd\xc1+\xfc\x1d\xa9\xcdb9y\x8cF+RW4\x89)\x99\xcb\xdc\xf5\xbe\xf5\xa7J\xf2\x95'
Hdu7PqjA1p55GAcBiULmCAfzoksdwW1oSxaMH83kw9BJ
b'jf\x10J>\xb9O]\x14\xab}d,r\x88(B\xab\x9a\xb1x\x18\x04\xeb\x10!\x9f\xebY\xa5v"'
8ALUvxZ5Q1qQEsPUcHsoAzuzEp8Bm4HQpYqNNSafjDAR
For blocks, seals, signatures and etc, mitum uses yyyy-MM-dd HH:mm:ss.* +0000 UTC
expression and yyyy-MM-ddTHH:mm:ss.*Z
as standard.
All other timezones are not allowed! You must use only +0000 timezone for mitum.
For example,
-
When converting timestamp to byte format for generating block/seal/fact_sign hash
- converting the string
2021-11-16 01:53:30.518 +0000 UTC
to bytes format
- converting the string
-
When putting timestamp in block, seal, fact_sign or etc
- converting the timestamp to
2021-11-16T01:53:30.518Z
and put it in json
- converting the timestamp to
To generate operation hash, mitum concatenates byte arrays of network id, fact hash and byte arrays of fact_signs.
And to generate the byte array of a fact_sign, mitum concatenates byte arrays of signer, signature digest and signed_at.
Be careful that the format of signed_at
when converted to bytes is like yyyy-MM-dd HH:mm:ss.* +0000 UTC
but it will be expressed as yyyy-MM-ddTHH:mm:ss.*Z
when putted in json.
There is one more thing to note.
First at all, you don't have to care about decimal points of second(ss.*) in timestamp.
Moreover, you can write timestamp without .
and any number under .
.
However, you should not put any unnecessary zeros(0) in the float expression of second(ss.*) when converting timestamp to bytes format.
For example,
-
2021-11-16T01:53:30.518Z
is converted to2021-11-16 01:53:30.518 +0000 UTC
without any change of the time itself. -
2021-11-16T01:53:30.510Z
must be converted to2021-11-16 01:53:30.51 +0000 UTC
when generating hash. -
2021-11-16T01:53:30.000Z
must be converted to2021-11-16T01:53:30 +0000 UTC
when generating hash.
Any timestamp with some unnecessary zeros putted in json doesn't affect to effectiveness of the block, seal, or operation. Just pay attention when convert the format.