Protocon Network Document

안녕하세요! 프로토콘 네트워크 문서입니다.

Protocon Network

Protocon은 프로토콜 기반으로 스스로 운영되는 디지털 경제를 구축하는 것을 목표로 하는 블록체인 프로젝트입니다.
Protocon의 합의 프로토콜인 ISAAC+는 실제 산업에 사용할 수 있도록 대규모 데이터 처리에 적합하게 설계되었으며, 블록체인 기술을 필요로 하는 모든 영역에 사용될 수 있도록 범용성을 확보했습니다. 이를 토대로 프로토콜 기반의 순수 디지털 경제를 촉진할 것입니다
Protocon에 대한 자세한 내용을 위해 Protocon 를 방문하세요.

Contents

Mitum Protocol

What is MITUM?

Mitum은 유연하고 탄력적인 범용 프라이버시 블록체인입니다.
Mitum은 다양한 목적으로 사용될 수 있습니다.
  • 암호화폐 네트워크와 같은 public과 private 블록체인

  • 임의의 데이터를 위한 데이터 중심 블록체인

  • 안전한 익명 투표 시스템

MITUM에 대해 더 알고 싶다면, Mitum Doc 에 방문하세요.

Mitum Technical SPEC

  • Mitum(blockchain core framework)는 PBFT에 기초한 ISAAC+ 합의 프로토콜을 사용합니다.

  • 네트워크 전송 프로토콜은 quic (udp 기반)입니다.

  • Gossip-Based Node Discovery Protocol.

  • 블록체인의 메인 스토리지 엔진은 MongoDB 를 사용하며 로컬 파일 시스템이 블록 스토리지로 사용됩니다.

  • operation 병렬 처리

  • Main hash algorithm: Keccak 256, SHA-3

  • 지원하는 hash algorithm: Keccak 256, Keccak 512, Raw bytes.

  • 지원하는 message serialization format: JSON, BSON

  • 적은 양의 코드.

  • JSON logging

Seal and Operation

Operation

Mitum 블록체인 네트워크에서 operation은 데이터를 변경하는 명령의 단위입니다.
예를 들어, Mitum Currency는 create-account, transfer, key-updater, currency-register, currency-policy-updater, suffrage-infration operation을 지원합니다.
각 operation은 그 내용에 따라 개인키로 서명한 서명이 필요합니다.
operation의 fact는 실행할 내용을 담고 있으며 fact는 내용을 요약하는 hash 값이 포함되어 있습니다.

Fact and token

모든 operation은 fact를 포함하고 있습니다. 한 마디로, operation의 내용은 실재로는 fact에 들어있습니다.
fact는 Mitum 블록체인 네트워크에서 중요한 역할을 합니다.
  • fact hash는 처리된 operation을 대표하는 값입니다.

  • fact hash 블록체인에서 고유값을 가집니다.

  • operation이 블록에 저장되었는지는 fact hash를 검색해 확인할 수 있습니다.

이때, fact의 내용은 중복될 수 있습니다.
예를 들어, 동일한 내용의 두 트랜잭션은 token 이라는 요소의 도움 없이는 자연스럽게 같은 fact hash를 가지게 되며 Mitum 블록체인은 이를 다음과 같이 처리합니다.
- `sender A가 receiver B에게 토큰 100을 보낸다`는 항상 같은 fact 내용을 가집니다.
- 그러므로 같은 fact 내용만으로 만든 fact의 hash 값은 중복될 가능성이 있습니다.
- 만약 fact hash가 중복된 여러 개의 operation이 있을 경우 오직 첫 번째 operation만이 처리되며 나머지는 무시됩니다.
그렇다면, 같은 내용을 가진 fact는 다시 보낼 수 없을까요?
걱정하지 마세요. 각 fact에는 fact를 고유하게 만들어주는 token 값이 포함되어 있습니다.
token은 operation에 추가되어야 하는 필수적인 값입니다.
{
    "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
    "hash": "3Zdg5ZVdNFRbwX5WU7Nada3Wnx5VEgkHrDLVLkE8FMs1",
    "token": "cmFpc2VkIGJ5",
    "sender": "8PdeEpvqfyL3uZFHRZG5PS3JngYUzFFUGPvCg29C2dBnmca",
    "items": [
        {
            "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
            "keys": {
                "_hint": "mitum-currency-keys-v0.0.1",
                "keys": [
                    {
                        "_hint": "mitum-currency-key-v0.0.1",
                        "weight": 100,
                        "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                    }
                ],
                "threshold": 100
            },
            "amounts": [
                {
                    "_hint": "mitum-currency-amount-v0.0.1",
                    "amount": "333",
                    "currency": "MCC"
                }
            ]
        }
    ]
}
token은 memo와 비슷하지만, 같은 fact 내용에 대해 고유한 token을 사용함으로써 fact를 고유하게 만들어주는 특성이 있습니다.
모든 operation의 fact를 고유하게 만드는 것은 많은 방향으로 사용성을 확장시킵니다.
  • 가장 큰 이점은 token과 fact의 정확한 내용을 알고 있으면 operation이 처리되었는지 간단히 확인할 수 있다는 것입니다.

  • sender, receiver, currencyID, amount, 그리고 특정 token 값을 알고 있으면 누구나 fact hash를 계산할 수 있습니다.

  • 그러므로 fact hash에 상응하는 operation이 처리되었는지 누구나 알 수 있습니다.

fact hash는 블록체인에 기록되는 공개 증명과 같습니다. 만약 블록체인에 게시된 증명을 잘 사용하면 다양하게 응용할 수 있습니다.
예를 들자면 블록체인에 직접 계정을 가지지 않은 외부인도 operation이 처리되었는지를 나타내는 유일한 값인 fact hash를 알아내고 조건에 맞게 구현할 수 있습니다.
게다가 fact와 token들은 송금뿐만이 아닌 다양한 데이터를 다루는 모델에 유용하게 사용될 수 있습니다.

Seal

Seal은 operation의 모음으로 네트워크에 전송됩니다. 즉, operation이 seal에 담겨 전송됩니다.
  • seal을 전송하기 위해, 개인키로 만든 서명이 필요합니다.

  • 서명을 생성하기 위해 Mitum의 키페어 패키지로부터 생성한 개인키가 필요합니다.

  • seal은 최대 100 개의 operation을 담을 수 있습니다.

seal 서명에 사용되는 개인키는 블록체인 상에서 아무것도 할 필요가 없습니다. 즉, 해당 개인키는 등록된 계정의 키일 필요가 없습니다.

Send

operation 생성 후, 클라이언트는 서명을 생성 해 seal에 붙입니다.
  • seal에 담을 수 있는 최대 operation 수 내에서 필요한 가능한 많은 operation을 만들어 seal에 담으세요.

  • seal 서명을 생성해 추가하세요.

  • Mitum 노드에 seal을 전송하세요.

Stored in Block

블록체인 네트워크에 전송된 operation은 그 operation이 정상적이고 블록에 쌓인 경우 계정의 상태를 변화시킵니다.
operation이 블록에 저장되었는지 rest api 를 통해 확인할 수 있습니다.

Block Data

Block data in Mitum Node

Mitum에서 블록 데이터는 두 공간에 저장됩니다: 데이터베이스, 파일 시스템
  • 데이터베이스는 합의에 사용되는 다음과 같은 정보를 저장합니다.

blockdata_map
info
manifest: block header
operation: operation fact
operation
proposal
seal
state: state data by each block
voteproof
  • 파일 시스템은 다음과 같은 모든 블록 데이터를 저장합니다.

manifest
operations of block
states of block
proposal
suffrage information
voteproofs(and init and accept ballots)
  • 데이터베이스에 저장된 블록 데이터는 mitum 노드를 실행하고 정상적으로 네트워크에 참여하기 위해 필요합니다.

  • 파일 시스템의 블록 데이터는 런타임에 사용되지 않으며 syncing 노드에 블록 데이터를 제공하는데 사용됩니다.

온전한 노드는 블록 데이터를 동기화하길 원하는 다른 노드들을 위해 블록 데이터를 제공해야 합니다.

BlockDataMap

기본적으로 블록 데이터는 로컬 파일 시스템에 저장됩니다.
blockdatamap은 실제 블록 데이터가 어디에 위치해있는지에 대한 정보를 포함합니다.
{
    "_hint": "base-blockdatamap-v0.0.1",
    "hash": "2ojLCZwG5J7xmfoxiBbhvJsc6dDTxDFDsw1nfPneT2xr",
    "height": 2,
    "block": "BcXqCKG5MbQcfuFpPtjvHcNBGeK6Pz3aG2cMcp4MUy9C",
    "created_at": "2021-06-14T03:20:24.887Z",
    "items": {
        "operations_tree": {
            "type": "operations_tree",
            "checksum": "1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26",
            "url": "file:///000/000/000/000/000/000/002/2-operations_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz"
        },
    },
    "writer": "blockdata-writer-v0.0.1"
}
이 BlockDataMap 예제에서, operation_tree 의 데이터는 file:///000/000/000/000/000/000/002/2-operations_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz 에 위치해있습니다.
BlockDataMap for block data stored in external storage
Mitum는 노드의 로컬 파일 시스템이 아닌 외부 스토리지에 블록 데이터를 저장하는 것을 지원합니다.
블록 데이터를 외부에 저장하기 위한 몇 가지 과정을 거치고 나면 blockdatamap은 다음과 같아집니다.
{
    "_hint": "base-blockdatamap-v0.0.1",
    "hash": "2ojLCZwG5J7xmfoxiBbhvJsc6dDTxDFDsw1nfPneT2xr",
    "height": 2,
    "block": "BcXqCKG5MbQcfuFpPtjvHcNBGeK6Pz3aG2cMcp4MUy9C",
    "created_at": "2021-06-14T03:20:24.887Z",
    "items": {
        "operations_tree": {
            "type": "operations_tree",
            "checksum": "1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26",
            "url": "fhttps://aws/2-operations_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz"
        },
    },
    "writer": "blockdata-writer-v0.0.1"
}
보이는 것처럼 url 은 외부 스토리지 서버로 교체됩니다.
How to update BlockDataMap for external Storage
예를 들어 block height 10의 블록 데이터가 외부 스토리지로 옮겨졌다고 가정해봅시다.
노드의 deploy key를 사용하겠습니다.
노드의 이 deploy key는 노드의 개인키 대신 사용되는 키입니다.
deploy key를 만드는 방법은 deploydeploy key 를 참고하세요.
블록 데이터 이동과 blockdatamap 업데이트 과정은 다음과 같습니다.
  • mitum 노드의 새로운 deploy key를 얻습니다.

  • storage download map 을 사용해 현재 blockdatamap을 내려받습니다.

  • block height 10의 모든 블록 데이터를 외부 스토리지에 업로드합니다. (example : AWS S3)

  • 내려받은 BlockDataMap의 url 필드값을 새로운 외부 스토리지 url로 교체합니다.

  • storage set-blockdatamaps 명령어를 실행하여 노드의 blockdatamap을 업데이트합니다.

  • 새롭게 업데이트 된 blockdatamap을 storage download map 명령어로 확인하세요.

blockdatamap을 성공적으로 업데이트하면 mitum 노드는 30초뒤 자동적으로 height 10의 모든 파일을 지웁니다.
$ DEPLOY_KEY=d-974702df-89a7-4fd1-a742-2d66c1ead6cd

$ NODE=https://127.0.0.1:54321

$ ./mitum storage download map 10 --tls-insecure --node=$NODE > mapData

$ cat mapData | jq
{
    "_hint": "base-blockdatamap-v0.0.1",
    "hash": "2ojLCZwG5J7xmfoxiBbhvJsc6dDTxDFDsw1nfPneT2xr",
    "height": 2,
    "block": "BcXqCKG5MbQcfuFpPtjvHcNBGeK6Pz3aG2cMcp4MUy9C",
    "created_at": "2021-06-14T03:20:24.887Z",
    "items": {
        "operations_tree": {
            "type": "operations_tree",
            "checksum": "1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26",
            "url": "file:///000/000/000/000/000/000/002/2-operations_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz"
        },
        "manifest": {
            "type": "manifest",
            "checksum": "6e53950e3ab87008b2bcb9841461588456c3e1069458eb8b150f1bfb97d22d42",
            "url": "file:///000/000/000/000/000/000/002/2-manifest-6e53950e3ab87008b2bcb9841461588456c3e1069458eb8b150f1bfb97d22d42.jsonld.gz"
        },
        "suffrage_info": {
            "type": "suffrage_info",
            "checksum": "e7584f9b5324566d4c5319db33ece980000f9c29eaf4d17befcc239743788f02",
            "url": "file:///000/000/000/000/000/000/002/2-suffrage_info-e7584f9b5324566d4c5319db33ece980000f9c29eaf4d17befcc239743788f02.jsonld.gz"
        },
        "states": {
            "type": "states",
            "checksum": "d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59",
            "url": "file:///000/000/000/000/000/000/002/2-states-d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59.jsonld.gz"
        },
        "operations": {
            "type": "operations",
            "checksum": "d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59",
            "url": "file:///000/000/000/000/000/000/002/2-operations-d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59.jsonld.gz"
        },
        "proposal": {
            "type": "proposal",
            "checksum": "dbbce4aaa6aece06596ecd45068008d35a41f592339d8898501b55f5843dbefe",
            "url": "file:///000/000/000/000/000/000/002/2-proposal-dbbce4aaa6aece06596ecd45068008d35a41f592339d8898501b55f5843dbefe.jsonld.gz"
        },
        "init_voteproof": {
            "type": "init_voteproof",
            "checksum": "705af3bd660070813354b572288204d787a949fc5411f3e2bc28e86f07bc1e64",
            "url": "file:///000/000/000/000/000/000/002/2-init_voteproof-705af3bd660070813354b572288204d787a949fc5411f3e2bc28e86f07bc1e64.jsonld.gz"
        },
        "accept_voteproof": {
            "type": "accept_voteproof",
            "checksum": "0d4296d44f96a3de216a90f99d77bf77a00ecd5102d7bbba612b13a57bdf2f34",
            "url": "file:///000/000/000/000/000/000/002/2-accept_voteproof-0d4296d44f96a3de216a90f99d77bf77a00ecd5102d7bbba612b13a57bdf2f34.jsonld.gz"
        },
        "states_tree": {
            "type": "states_tree",
            "checksum": "1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26",
            "url": "file:///000/000/000/000/000/000/002/2-states_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz"
        }
    },
    "writer": "blockdata-writer-v0.0.1"
}

$ aws s3 cp ./blockdata/000/000/000/000/000/000/002 s3://destbucket/blockdata/000/000/000/000/000/000/002 --recursive
# update mapData blockdata url from "file:///000/000/000/000/000/000/002/" to https://aws/"

$ ./mitum storage set-blockdatamaps $DEPLOY_KEY mapData $NODE --tls-insecure

$ ./mitum storage download map 2 --tls-insecure --node=$NODE
{
    "_hint": "base-blockdatamap-v0.0.1",
    "hash": "2ojLCZwG5J7xmfoxiBbhvJsc6dDTxDFDsw1nfPneT2xr",
    "height": 2,
    "block": "BcXqCKG5MbQcfuFpPtjvHcNBGeK6Pz3aG2cMcp4MUy9C",
    "created_at": "2021-06-14T03:20:24.887Z",
    "items": {
        "operations_tree": {
            "type": "operations_tree",
            "checksum": "1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26",
            "url": "fhttps://aws/2-operations_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz"
        },
        "manifest": {
            "type": "manifest",
            "checksum": "6e53950e3ab87008b2bcb9841461588456c3e1069458eb8b150f1bfb97d22d42",
            "url": "fhttps://aws/2-manifest-6e53950e3ab87008b2bcb9841461588456c3e1069458eb8b150f1bfb97d22d42.jsonld.gz"
        },
        "suffrage_info": {
            "type": "suffrage_info",
            "checksum": "e7584f9b5324566d4c5319db33ece980000f9c29eaf4d17befcc239743788f02",
            "url": "fhttps://aws/2-suffrage_info-e7584f9b5324566d4c5319db33ece980000f9c29eaf4d17befcc239743788f02.jsonld.gz"
        },
        "states": {
            "type": "states",
            "checksum": "d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59",
            "url": "fhttps://aws/2-states-d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59.jsonld.gz"
        },
        "operations": {
            "type": "operations",
            "checksum": "d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59",
            "url": "fhttps://aws/2-operations-d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59.jsonld.gz"
        },
        "proposal": {
            "type": "proposal",
            "checksum": "dbbce4aaa6aece06596ecd45068008d35a41f592339d8898501b55f5843dbefe",
            "url": "fhttps://aws/2-proposal-dbbce4aaa6aece06596ecd45068008d35a41f592339d8898501b55f5843dbefe.jsonld.gz"
        },
        "init_voteproof": {
            "type": "init_voteproof",
            "checksum": "705af3bd660070813354b572288204d787a949fc5411f3e2bc28e86f07bc1e64",
            "url": "fhttps://aws/2-init_voteproof-705af3bd660070813354b572288204d787a949fc5411f3e2bc28e86f07bc1e64.jsonld.gz"
        },
        "accept_voteproof": {
            "type": "accept_voteproof",
            "checksum": "0d4296d44f96a3de216a90f99d77bf77a00ecd5102d7bbba612b13a57bdf2f34",
            "url": "fhttps://aws/2-accept_voteproof-0d4296d44f96a3de216a90f99d77bf77a00ecd5102d7bbba612b13a57bdf2f34.jsonld.gz"
        },
        "states_tree": {
            "type": "states_tree",
            "checksum": "1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26",
            "url": "fhttps://aws/2-states_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz"
        }
    },
    "writer": "blockdata-writer-v0.0.1"
}

Blockchain Application Model

Mitum은 범용 블록체인으로 디자인 되었습니다. 이 요구를 충족하기 위해, Mitum의 정책 및 데이터는 실용적인 방법으로 구성 및 관리할 수 있습니다.
간단히 말해, 네트워크 디자이너는 네트워크를 두 부분으로 디자인 할 것입니다.
  • 데이터

  • 정책

데이터와 정책을 디자인함으로써 디자이너는 자신의 네트워크 모델을 구축하고 출시할 수 있습니다.
예를 들어, 디자이너가 Mitum에서 currency 모델을 빌드하고자 한다고 가정해봅시다. 그는 여러 currency를 정의할 수 있으며 관련 데이터와 추가적인 정책을 추가할 수 있습니다.
데이터 타입:
  • 계정

  • 잔액

정책:
  • 총량

  • 새 계정의 최소 잔액

  • 멀티 시그

  • 인플레이션

  • 기타…

다음 그림은 Mitum 블록체인 코어와 Mitum 모델의 관계를 나타냅니다.
Mitum Blockchain Layer

Digest Service

  • Digest Service는 Mitum에 저장된 블록 데이터를 저장하며 HTTP-based API로 서비스되는 내부 서비스입니다.

  • Digest Service에 대한 자세한 내용은 rest api 를 참고해주세요.

Mitum-based models

Mitum Currency

What is Mitum Currency

  • Mitum Currency는 Mitum 네트워크 위에서 운용되는 currency 모델입니다.

  • Mitum Currency는 특정 토큰에 대한 정책을 등록하거나 업데이트하고, 추가적인 토큰을 발행하고, 토큰을 전송하고 새로운 계정을 만들며 계정의 키를 업데이트할 수 있는 기능을 제공합니다.

Feature of Mitum Currency

  • Mitum Currency가 제공하는 주요 특징은 토큰과 관련한 다양한 분야의 비즈니스 요구를 충족합니다.

  • 새 계정 생성 시 다중 키가 등록될 수 있으며 관련 키들은 key update operation으로 교체될 수 있습니다.

  • Mitum Currency는 새로운 currency를 발행하고 정책을 사용자화 할 수 있습니다.

  • currency 정책은 필요할 때 언제나 업데이트 될 수 있습니다.

  • currency 정책을 등록하고 업데이트하기 위해서는 계정 키가 아닌 노드 키가 필요합니다.

  • 계정 키는 토큰 전송 및 계정 키 업데이트에 사용됩니다.

  • Mitum Currency 네트워크의 노드 구성은 Mitum의 노드 operation 정책에 따르며 자세한 내용은 Build Multi Nodes Network 에서 찾아볼 수 있습니다.

Support Operations

Operations for Currency

currency-register

Register new currency id

currency-policy-updater

Update currency policy

suffrage-infration

Increase amount of tokens

Operations for Account

create-account

Create new account

key-updater

Update account keys

transfer

Transfer amount of tokens

명령어로 위 operation을 생성하는 방법은 currency 를 참조하세요.

Mitum Currency Extension

What is Mitum Currency Extension

  • Mitum Currency Extension은 is 이름과 같이 Mitum Currency의 확장된 모델입니다.

  • Mitum Currency Extension는 Mitum Currency의 operation에 더해 컨트랙트 계정 생성 및 (컨트랙트 계정으로부터의)토큰 인출을 지원합니다.

Features of Mitum Currency Extension

  • Mitum Currency Extension을 통해 일반 계정이 아닌 컨트랙트 계정을 생성할 수 있습니다.

  • 컨트랙트 계정은 주소를 가지고 있지만, 일반 계정처럼 계정 키는 가지고 있지 않습니다.

  • 컨트랙트 계정은 operation의 전송자가 될 수 없습니다.

  • 일반적으로, 컨트랙트 계정이 스스로 토큰을 소유하거나 전송할 수 없지만, 컨트랙트 계정의 주인에 의해 컨트랙트 계정에 쌓인 토큰을 인출할 수 있습니다.

  • 모델 디자이너들은 콘트랙트 계정이 다른 사용자 정의 상태를 정의할 수 있는 모델을 개발할 수 있다.

Support Operations

  • Mitum Currency Extension 은 Mitum Currency 모델의 operation을 포함하고 있습니다.

Operations for Contract Account

create-contract-account

Create new contract account

withdraw

Withdraw tokens from contract account

명령어로 위 operation을 생성하는 방법은 currency-extension 를 참조하세요.

Mitum Document

What is Mitum Document

  • Mitum Document 는 문서 생성, 업데이트, 서명을 지원하는 도구입니다.

  • Mitum Documnent는 여러 종류(blocksign, blockcity 등)의 document 아이템을 등록할 수 있도록 도와줍니다. 하지만 여기서는 가장 일반적으로 사용되는 블록사인 모델을 기반으로 설명합니다.

Features of Mitum Document

  • Mitum Document는 모든 형식의 문서에 대응합니다.

  • 문서의 제목, 해시, 크기, 서명자 등을 함께 등록할 수 있습니다.

  • 문서 생성자는 문서를 업데이트할 수 있습니다.

  • 서명자로 등록된 계정은 생성된 문서에 서명자로서 서명할 수 있습니다.

  • 블록체인의 특성에 의해, 문서가 업데이트된 이력은 영구적으로 블록체인에 저장됩니다.

Document ID

각 문서 타입에 대해 Document ID 접미사가 존재합니다.
blockcity 의 경우,
  • user doc: cui

  • land doc: cli

  • voting doc: cvi

  • history doc: chi

blocksign 의 경우,
  • blocksign doc: sdi

Support Operations

  • Mitum Document는 Mitum Currency 모델의 operation을 포함합니다.

Operations for Document

create-document

Create new document

update-document

Update the registered document

sign-document

Sign the registered document

명령어로 위 operation을 생성하는 방법은 document 을 참조하세요.

Mitum Feefi

What is Mitum Feefi

  • Mitum Feefi는 Mitum 블록체인 네트워크를 기반으로 작동하는 금융 모델입니다.

  • Mitum Feefi는 새 토큰 쌍 풀을 등록하고, 풀 정책을 업데이트하고, 풀에 입금 및 출금하는 기능을 제공합니다.

  • Mitum Feefi가 작동하는 블록체인 네트워크는 수수료 교환에 대해 탈 중앙화되어 있습니다.

Features of Mitum Feefi

  • Mitum Feefi는 operation 수수료를 dApp 토큰으로 지불하는데 사용될 수 있습니다.

Support Operations

  • Mitum Feefi는 Mitum Currency Extension 모델의 operation을 포함하고 있습니다.

Operations for Feefi Pool

pool-register

Register new feefi pool

pool-policy-updater

Update pool policy

pool-deposit

Deposit tokens to pool

pool-withdraw

Withdraw tokens from pool

명령어로 위 operation을 생성하는 방법은 feefi 를 참조하세요.

Mitum NFT

What is Mitum NFT

  • Mitum NFT는 창작자와 저작자 개념이 포함된 NFT 모델입니다.

  • Mitum NFT는 NFT 컬랙션을 등록하거나 업데이트하고, 새로운 NFT를 민팅하고 이에 서명하거나 전송, 소각하는 기능과 함께 다른 계정에 NFT에 대한 권한을 위임할 수 있는 기능을 제공합니다.

Features of Mitum NFT

  • Mitum NFT를 통해 NFT 컬랙션에 로열티 정보를 미리 등록할 수 있습니다.

  • NFT 컬랙션 생성자는 컬랙션에 민팅할 수 있는 계정들의 목록인 화이트리스트를 설정할 수 있습니다.

  • NFT를 민팅할 때 창작자와 저작권자 및 그들 각각에 대한 지분을 함께 설정할 수 있습니다.

  • NFT의 창작자와 저작권자는 권리자로서 NFT에 서명할 수 있습니다.

Support Operations

  • Mitum NFT는 Mitum Currency Extension의 operation을 포함합니다.

Operations for NFT Collection

collection-register

Register new nft collection

collection-policy-updater

Update nft collection

Operations for NFT

mint

Mint new nft

sign

Sign nft as creator or copyrighter

transfer

Transfer nft

burn

Burn(Deactivate) nft

Operations for Delegation of Authority

delegate

Delegation of authority to nfts of collection

approve

Delegation of authority to any one nft

명령어를 통해 위 operation을 생성하는 방법은 nft 를 참조해주세요.

Quick Start

이 장에서는 노드를 어떻게 실행하는지 소개합니다.
우선, docker 와 golang 를 먼저 설치하세요.
원활한 설명을 위해 이 장에서는 Mitum Currency를 예시로 사용합니다.

About Mitum Currency Node

Mitum Blockchain는 PBFT-based ISAAC+ 합의 프로토콜을 사용합니다.
ISAAC+ 합의 프로토콜에서, 모든 노드들은 같은 역할을 하며 블록 생성에 참여합니다.
네트워크에 참여하는 노드들은 다음 임무를 수행합니다.
  • Make Proposal

  • Block Verification

  • Voting

  • Store Block

  • Provide Digest API Service

  • Transaction Request Collection

Mitum Blockchain 네트워크에 대한 더 많은 정보는 Mitum Doc 에서 확인하세요.

Prerequisite

Database
Mitum은 MongoDB를 메인 스토리지 엔진으로 사용합니다.
노드를 운용하기 위해 mongodb를 먼저 준비해야 합니다.
Installation and Setup
$ docker run --name <db name> -it -p <host port>:<container port> -d mongo
Golang
Mitum과 Mitum 모델은 Go 언어로 개발되었습니다.
실행가능한 바이너리를 생성하기 위해 소스코드를 빌드해야 합니다.
Go 언어를 설치하기 위한 자세한 방법은 제공하지 않습니다.
Mitum을 빌드하기 위해 최소 버전 1.17의 golang이 설치되어야 합니다.
더 자세한 사항은 How to Install Go 을 참고하세요.

Installation

  • Mitum Currency 의 소스코드를 다운로드 해주세요.

  • Git 을 사용하면,

$ git clone https://github.com/spikeekips/mitum-currency.git
  • exe 파일을 빌드하세요.

$ cd mitum-currency

$ go build -ldflags="-X 'main.Version=v0.0.1-tutorial'" -o ./mitum ./main.go

$ ./mitum version
v0.0.1
  • 다른 모델들의 설치 방법도 위와 같습니다.

Mitum과 각 모델의 모든 명령어는 Command Line Interface 에서 확인할 수 있습니다.

Configuration

노드 설정을 위한 구성은 YAML으로 작성됩니다.

address

로컬 노드의 주소 (url 주소 별칭)
address: n0sas

genesis-operations

genesis-operation 은 네트워크 초기화 시 실행되는 제네시스 operation에 대한 설정입니다.
genesis-operation 은 최초로 생성되는 블록의 내용을 담고 있습니다.
currency 모델에서는 메인 currency와 제네시스 계정의 정보가 설정되어야 합니다.
등록하는 정보는 다음과 같습니다.
  • *genesis account*의 키 (key, weight, threshold)

  • 최초 잔액

  • Currency ID

  • 생성될 currency의 수수료 정책

예시는 다음과 같습니다.
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
          new-account-min-balance: "33"
    type: genesis-currencies

network

네트워크에 사용되는 노드의 domain address 혹은 IP address 를 설정합니다.
network는 quic communication protocol을 사용하여 노드나 클라이언트로부터 메시지를 받기 위한 주소입니다.
테스트 노드를 구성하기 위해 Self-signed certificates가 사용될 수 있습니다. 보안이 크게 문제가 되지 않는 테스트 및 개발 노드에만 사용할 수 있습니다.
$ openssl genrsa -out mitum.key 4096

$ openssl req -x509 -new -nodes -key mitum.key -sha256 -days 1024 -out mitum.crt
예시는 다음과 같습니다.
network:
    bind: https://0.0.0.0:54321
    url: https://127.0.0.1:54321
    cert-key: mitum.key
    cert: mitum.crt
rate-limit
기본적으로, 인터넷 서비스의 API 인터페이스는 제한 없이 클라이언트로부터의 연결을 허용합니다.
하지만 서비스에 지나치게 많은 요청이 들어오면 서비스의 성능을 해칠 수 있습니다.
서비스를 안정적으로 유지하기 위해 API 서비스에 rate limit 가 적용될 수 있습니다.
Rate limiting 에 대해 확인하세요.
Mitum은 none-suffrage 노드들을 포함한 노드들 간의 통신을 위해 quic 기반 API 인터페이스를 제공합니다.
또한, Mitum Currency는 digest라 불리는 http2 기반 API 서비스를 제공합니다.
rate-limit 가 이런 API 서비스에 적용됩니다.
network:
    bind: https://0.0.0.0:54321
    url: https://127.0.0.1:54321

    rate-limit:
        cache: "memory:?prefix=showme"
        preset:
            bad-nodes:
                new-seal: 3/2m
                blockdata: 4/m
        3.3.3.3:
            preset: bad-nodes
        4.4.4.4/24:
            preset: bad-nodes
            blockdata: 5/m
        127.0.0.1/24:
            preset: suffrage
  • cache: 요청에 대한 캐시. 이때, “memory:”와 “redis://<redis server>”를 지원합니다.

    • memory: memory cache

    • redis://<redis server>: cached in redis server

  • preset: 사전 정의된 rate limit 설정.

    • Mitum에대한 suffrageworld 프리셋은 이미 정의되어 있습니다. launch/config/ratelimit.go 소스코드에서 확인하세요.

    • bad-nodes와 같은 자신만의 rate limit 설정을 만들수도 있습니다.

  • Rules:

    • 특정 IP에 대한 Rate-limit 설정

    • 규칙은 IP address (또는 IP address 범위), preset 그리고 자세한 rate-limit 설정으로 구성되어 있습니다.

    • IP 주소는 단일 값이나 CIDR 표기법으로 표현된 IP 주소의 범위일 수 있습니다. * example : 3.3.3.3, 4.4.4.4/24, 127.0.0.1/24

    • Rate limit는 preset 과 추가적인 limits 으로 설정될 수 있습니다.

    • preset``는 ``suffrage, world 와 같은 사전 정의된 프리셋이나 bad-nodes 와 같은 사용자화 프리셋일 수 있습니다.

    • blockdata: 5/m 과 같은 추가적인 limit이 preset 에 추가될 수 있습니다.

    • 규칙은 정의된 순서대로 확인됩니다. 상위 규칙이 먼저 확인됩니다.

  • Detailed limit:

    • limit 설정에 사용되는 new-seal과 같은 Mitum API 인터페이스의 이름은 RateLimitHandleMap(launch/config/ratelimit.go)에서 확인할 수 있습니다..

    • Mitum Currency API 인터페이스의 이름은 RateLimitHandlerMap(digest/handler.go)에서 확인할 수 있습니다.

    • new-seal: 3/2m은 new-seal 인터페이스가 특정 IP, IP 주소 범위에 대해 2분에 3 요청을 허용한다는 뜻입니다.

    • time duration의 방법을 확인하세요.

  • 다른 규칙이 설정되지 않으면 기본적으로 rate limit이 없습니다.

0보다 작은 late limit은 unlimited를 뜻합니다.
다음 예시입니다,
4.4.4.4/24:
preset: bad-nodes
blockdata: -1/m
0 limit 값은 요청을 차단한다는 뜻입니다.
For example,
4.4.4.4/24:
    preset: bad-nodes
    blockdata: 0/m

network-id

network id 는 네트워크를 식별하는 식별자의 역할을 합니다.
같은 네트워크의 모든 노드들은 같은 network id 값을 가집니다.
다음은 예시입니다.
network-id: mitum

keypair

노드의 개인키를 기입하세요.
예시입니다.
privatekey: Kxt22aSeFzJiDQagrvfXPWbEbrTSPsRxbYm9BhNbNJTsrbPbFnPAmpr
키페어 생성 방법은 key 을 참고하세요.

storage

블록체인 데이터 스토리지의 파일 시스템 경로와 mongodb 데이터베이스 주소를 설정하세요.
블록 데이터 설정이 없으면, blockdata > path 가 현재 경로의 blockdata라고 불리는 폴더로 기본 설정됩니다.
다음은 예시입니다.
storage:
blockdata:
    path: ./mitum-blockfs
database:
    uri: mongodb://127.0.0.1:27017/mc
port number 는 docker를 실행할 때의 것과 같아야합니다.

suffrage

nodes
합의에 참여하는 suffrage 노드의 주소를 설정하세요.
로컬 노드의 별칭은 n0sas 입니다.
만약 n0, n1, n2, n3 노드가 suffrage 노드로 추가되면 설정은 다음과 같아집니다.
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
만약 로컬 노드인 n0 가 suffrage 노드로 추가되지 않으면 로컬 노드는 None-suffrage 노드가 되며 syncing node 로서만 운용되게 됩니다.
  • Syncing node 는 합의에 참여하지 않으며 오직 블록 데이터를 동기화하기만 합니다.

  • None-suffrage 노드는 operation을 담은 seal만 다룹니다.

  • None-suffrage 노드는 노드 사이의 voting과 관련된 ballot과 proposal을 처리하지 않습니다.

  • None-suffrage 노드가 operation seal을 저장할 때, 이를 suffrage 노드에 브로드캐스팅합니다.

만약 None-suffrage 노드가 다른 노드들을 suffrage 노드에 추가하지 않으면, 혹은 다른 suffrage 노드를 구성하지 않으면 operation seal이 처리될 수 없습니다.
suffrage:
    nodes:
        - n1sas
        - n2sas
        - n3sas

sync-interval

None-suffrage 노드는 주기적으로 블록데이터를 동기화합니다.
기본 주기는 10초입니다.
sync-interval 설정을 통해 주기를 변경할 수 있습니다.
sync-interval: 3s

nodes

블록체인 네트워크의 알려진 노드들의 address, public key, url 를 입력합니다.
  • 작성하지 않으면 standalone node 로서 운용되게 됩니다.

  • 노드가 suffrage 노드이거나 node discovery 기능이 사용되면, 노드의 url 는 필요하지 않습니다.

  • 하지만 노드가 suffrage 노드가 아닌 경우 suffrage 노드들의 url 입력되어야 합니다.

Mitum 노드들은 기본적으로 CA signed certificate (public certificate)를 사용합니다.
  • 만약 설정과 관련된 certificate가 Network config 에 설정되지 않으면 노드는 self-signed certificate 를 사용합니다.

  • 다른 Mitum 노드들이 self-signed certificate를 사용하면, self-signed certificate를 사용하는 모든 노드들에 tls-insecure: true 가 설정되어야 합니다.

(In case of suffrage node)

nodes:
    - address: n1sas
    publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
    tls-insecure: true
    - address: n2sas
    publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
    tls-insecure: true
    - address: n3sas
    publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
    tls-insecure: true
(If it is not a suffrage node)

nodes:
    - address: n1sas
    publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
    url: https://127.0.0.1:54331
    tls-insecure: true
    - address: n2sas
    publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
    url: https://127.0.0.1:54341
    tls-insecure: true
    - address: n3sas
    publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
    url: https://127.0.0.1:54351
    tls-insecure: true

digest

API 접근 시의 APIIP address 에서 제공하는 데이터를 저장하는 mongodb address 를 지정하세요.
digest:
    network:
        bind: https://localhost:54320
        url: https://localhost:54320
        cert-key: mitum.key
        cert: mitum.crt

tutorial.yml

다음은 standalone 노드 구성의 한 예제입니다.
address: mc-nodesas
privatekey: Kxt22aSeFzJiDQagrvfXPWbEbrTSPsRxbYm9BhNbNJTsrbPbFnPAmpr
storage:
    database:
        uri: mongodb://127.0.0.1:27017/mc
    blockdata:
        path: ./mitum-blockfs
network-id: mitum
network:
    bind: https://0.0.0.0:54321
    url: https://127.0.0.1:54321
    cert-key: mitum.key
    cert: mitum.crt
genesis-operations:
    - type: genesis-currencies
    account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
                weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
            currency: MCC
            new-account-min-balance: "33"
            feeer:
                type: fixed
                amount: 1
policy:
    threshold: 100
suffrage:
    nodes:
        - mc-nodesas

digest:
    network:
        bind: https://0.0.0.0:54320
        url: https://127.0.0.1:54320
        cert-key: mitum.key
        cert: mitum.crt

Run

노드 운용 과정을 설명합니다.

참고

  • 노드는 node discovery 프로토콜을 사용해 모든 노드의 주소를 알아낼 수 있습니다.

  • 각 Mitum 모델에는 Digest API가 추가되어 있습니다. 따라서 API 서비스가 기본적으로 제공됩니다.

  • Digest 설정을 위해 Configuration 를 참고하세요.

  • Digest가 설정되지 않으면 API 서비스를 위한 데이터가 별도로 처리됩니다.

Running the Standalone Node

노드를 운용하기 전에 Configuration 를 참고해 config 파일을 준비해주세요.
node init
우선, genesis block과 genesis account가 생성되어야 합니다. 메인 currency는 genesis block과 함께 발행되며 genesis account의 잔액으로 저장됩니다.
  • tutorial.yml : config file

$ ./mitum node init --log-level info <config file>
2021-06-10T05:13:09.232802Z INF dryrun? dryrun=false module=command-init
2021-06-10T05:13:09.235942Z INF prepare to run module=command-init
2021-06-10T05:13:09.236013Z INF prepared module=command-init
2021-06-10T05:13:09.780335419Z INF genesis block created block={"hash":"6HjkXEhTNhPzUTG167jsTEany3dHebDQ5cKGNTNEzcgh","height":0} module=command-init
2021-06-10T05:13:10.786661419Z INF stopped module=command-init
...

참고

만약 이미 저장된 블록이 확인되면 environment already exists: block=0 에러가 발생합니다. 이 에러를 초기화하고 무시하려면 --force 옵션과 함께 실행하세요.

$ ./mitum init <config file> --force

node run
노드가 실행되면 블록체인 스토리지 상태와 합의 참여 상태가 SYNC, JOIN, CONSENSUS 모드로 변경되며 블록 생성이 시작됩니다.
$ ./mitum node run --log-level info <config file>
2021-06-10T05:14:08.225487Z INF dryrun? dryrun=false module=command-run
2021-06-10T05:14:08.228797Z INF prepare to run module=command-run
2021-06-10T05:14:08.228869Z INF prepared module=command-run
2021-06-10T05:14:09.706271049Z INF new blocks found to digest last_block=-2 last_manifest=0 module=command-run
2021-06-10T05:14:09.827980049Z INF digested new blocks module=command-run
2021-06-10T05:14:09.828967049Z INF trying to start http2 server for digest API bind=https://localhost:54320 module=command-run publish=https://localhost:54320
2021-06-10T05:14:11.894638049Z INF new block stored block={"hash":"CC57VpSKPozBRABPnznyMk6QY4GHn7CiSH4zSZBs8Rri","height":1,"round":0} elapsed=17.970959 module=basic-consensus-state proposal_hash=DJBgmoAJ4ef7h7iF6E3gTQ83AjWxbGDGQrmDSiQMrfya voteproof_id=BAg2HCNfBenFebuCM4P4HkDfF1off8FCBcSejdK1j7w6
2021-06-10T05:14:11.907600049Z INF block digested block=1 module=digester
Lookup Genesis Account
파일 시스템에 저장된 블록을 통해 genesis account 정보를 확인할 수 있습니다.
다음은 예시입니다.
$ find blockfs -name "*-states-*" -print | xargs -n 1 gzcat | grep '^{' | jq '. | select(.key == "9g4BAB8nZdzWmrsAomwdvNJU2hA2psvkfTQ5XdLn4F4r-mca:account") | [ "height: "+(.height|tostring), "state_key: " + .key, "address: " + .value.value.address, .operations, .value.value.keys.keys, .value.value.keys.threshold]'
[
    "height: 0",
    "state_key: 9g4BAB8nZdzWmrsAomwdvNJU2hA2psvkfTQ5XdLn4F4r-mca:account",
    "address: CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
    [
        "ECSDvWwxcjbEw2F3E6n6pyQXMsZn2uy7msX19XXDCYi8"
    ],
    [
        {
        "_hint": "mitum-currency-key-v0.0.1",
        "weight": 100,
        "key": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu"
        }
    ],
    100
]
$ find blockfs -name "*-states-*" -print | xargs -n 1 gzcat | grep '^{' |jq '. | select(.key == "9g4BAB8nZdzWmrsAomwdvNJU2hA2psvkfTQ5XdLn4F4r-mca-MCC:balance") | [ "height: "+(.height|tostring), "state_key: " + .key, "balance:" + .value.value.amount]'
[
    "height: 0",
    "state_key: 9g4BAB8nZdzWmrsAomwdvNJU2hA2psvkfTQ5XdLn4F4r-mca-MCC:balance",
    "balance:99999999999999999999"
]
  • height 0 의 genesis account 주소, CoXPgSxcad3fRAbp2JBeeGcYGEQ7dQhdZGWXLTHPwuGmca 가 블록에 저장됩니다.

Lookup using Digest API
Digest API를 통해 계정 정보를 확인할 수 있습니다.
digets 설정 Configuration 에 따른 api 주소는 https://localhost:54320 입니다.
account 정보를 통해 genesis account를 확인하세요.
$ curl --insecure http://localhost:54320/account/CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca | jq '{_embedded}'
{
    "_embedded": {
        "_hint": "mitum-currency-account-value-v0.0.1",
        "hash": "6vCuuiqaYtNGfPbqfDqA234kiDoueWejd7jMs7dwvq5U",
        "address": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
        "keys": {
            "_hint": "mitum-currency-keys-v0.0.1",
            "hash": "9g4BAB8nZdzWmrsAomwdvNJU2hA2psvkfTQ5XdLn4F4r",
            "keys": [
                {
                "_hint": "mitum-currency-key-v0.0.1",
                "weight": 100,
                "key": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu"
                }
            ],
            "threshold": 100
        },
        "balance": [
            {
                "_hint": "mitum-currency-amount-v0.0.1",
                "amount": "99999999999999999999",
                "currency": "MCC"
            }
        ],
        "height": 0,
        "previous_height": -2
    }
}

Build Multi Nodes Network

Order of Execution
  1. 멀티 노드를 실행할 때 genesis block을 생성하는 첫 노드가 설정되어야 합니다. 첫 노드는 node init 을 통해 genesis block을 생성합니다. genesis block를 만들지 않는 그 외의 노드들은 init 을 실행할 필요가 없습니다.

  2. 첫 노드는 init 뒤에 run 을 실행해 노드를 시작합니다.

  3. 다른 노드들도 run 로 노드를 시작합니다.

  4. 다른 노드들은 sync 과정을 통해 첫 노드의 블록을 따라가며 노드들은 consensus 과정을 통해 블록을 생성합니다.

만약 4 개의 노드가 있고 그 중 n0이 첫 노드라면, 실행 순서는 다음과 같습니다. 모든 4 노드가 suffrage 노드일 때 노드들은 node discovery를 위해 최소 하나의 다른 노드의 publish url을 discovery url로 설정해야 합니다.
# n0 node
$ ./mitum node init <n0 config file>
$ ./mitum node run <n0 config file> --discovery <n1 publish url>
# n1 node
$ ./mitum node run <n1 config file> --discovery <n0 publish url>
# n2 node
$ ./mitum node run <n2 config file> --discovery <n0 publish url>
# n3 node
$ ./mitum node run <n3 config file> --discovery <n0 publish url>

참고

같은 네트워크에서 운용된다면 노드들은 구성 파일의 다음 요소에 대해 같은 값을 가져야 합니다.

  • genesis-operations

  • network-id

Four Suffrage Nodes
우리가 네 개의 suffrage 노드들을 운영하려는 상황이라고 가정해봅시다.
우선, 각 노드마다 yml config 파일을 준비하세요.
n0, n1, n2, n3 가 모두 suffrage 노드입니다.
Four Suffrage Nodes
노드에 따라, 합의에 참여하는 노드를 설정해야 합니다.
# Only ``suffrage`` and ``nodes`` part of configuration of suffrage nodes

suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas

nodes:
    - address: n0sas
    publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
    tls-insecure: true
    - address: n1sas
    publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
    tls-insecure: true
    - address: n2sas
    publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
    tls-insecure: true
    - address: n3sas
    publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
    tls-insecure: true
다음은 모든 노드의 전체 yml 구성의 예제입니다.
# n0 node

address: n0sas
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54321
    url: https://127.0.0.1:54321
network-id: mitum
policy:
    threshold: 100
privatekey: Kxt22aSeFzJiDQagrvfXPWbEbrTSPsRxbYm9BhNbNJTsrbPbFnPAmpr
publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
storage:
    blockdata:
        path: ./n0_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27017/n0_mc
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
nodes:
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      tls-insecure: true
    - address: n2sas
      publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      tls-insecure: true
# n1 node
address: n1sas
genesis-operations:
    - account-keys:
        keys:
            - privatekey: L5GTSKkRs9NPsXwYgACZdodNUJqCAWjz2BccuR4cAgxJumEZWjokmpr
              publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54331
    url: https://127.0.0.1:54331
network-id: mitum
policy:
    threshold: 100
privatekey: L4R2AZVmxWUiF2FrNEFi6rHwCTdDLQ1JuQHji69SbMcmWUdNMUSFmpr
publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
storage:
    blockdata:
        path: ./n1_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27018/n1_mc
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
nodes:
    - address: n0sas
      publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
      tls-insecure: true
    - address: n2sas
      publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      tls-insecure: true
# n2 node
address: n2sas
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54332
    url: https://127.0.0.1:54332
network-id: mitum
policy:
    threshold: 100
privatekey: L3Szj4t3w33YLsGFGeaB3v1vwae82yp5KWPcT7v1Y4WyQkAH7eCRmpr
publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
storage:
    blockdata:
        path: ./n2_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27019/n2_mc
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
nodes:
    - address: n0sas
      publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
      tls-insecure: true
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      tls-insecure: true
# n3 node
address: n3sas
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54333
    url: https://127.0.0.1:54333
network-id: mitum
policy:
    threshold: 100
privatekey: KwxfBSzwevSggJz2grf8FWrjvXzrctY3WismTy6GNdJpWXe5tF5Lmpr
publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
storage:
    blockdata:
        path: ./n3_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27020/n3_mc
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
nodes:
    - address: n0sas
      publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
      tls-insecure: true
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      tls-insecure: true
    - address: n2sas
      publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
      tls-insecure: true
Four Suffrage Nodes and One Sync Node
네 개의 suffrage 노드와 하나의 sync 노드(non-suffrage)를 운영하는 경우,
각 노드에 대해 yml config 파일을 준비하세요.
n0, n1, n2, n3 는 suffrage 노드이며 n4 가 sync 노드입니다.
Four Suffrage Nodes
suffrage 노드들(n0, n1, n2, n3) 구성의 suffragenodes 는 다음과 같습니다.
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas

nodes:
    - address: n0sas
      publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
      tls-insecure: true
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      tls-insecure: true
    - address: n2sas
      publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      tls-insecure: true
sync 노드(n4) 구성의 suffragenodes 은 다음과 같습니다.
# suffrage and nodes part of configuration

suffrage:
    nodes:
        - n1sas
        - n3sas
nodes:
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      url: https://127.0.0.1:54331
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      url: https://127.0.0.1:54351
      tls-insecure: true
다음은 모든 노드의 전체 yml의 예제입니다.
# n0 node(Suffrage node)

address: n0sas
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54321
    url: https://127.0.0.1:54321
network-id: mitum
policy:
    threshold: 100
privatekey: Kxt22aSeFzJiDQagrvfXPWbEbrTSPsRxbYm9BhNbNJTsrbPbFnPAmpr
publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
storage:
    blockdata:
        path: ./n0_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27017/n0_mc
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
nodes:
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      tls-insecure: true
    - address: n2sas
      publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      tls-insecure: true
# n1 node(Suffrage node)

address: n1sas
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54331
    url: https://127.0.0.1:54331
network-id: mitum
policy:
    threshold: 100
privatekey: L4R2AZVmxWUiF2FrNEFi6rHwCTdDLQ1JuQHji69SbMcmWUdNMUSFmpr
publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
storage:
    blockdata:
        path: ./n1_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27018/n1_mc
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
nodes:
    - address: n0sas
      publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
      tls-insecure: true
    - address: n2sas
      publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      tls-insecure: true
# n2 node(Suffrage node)

address: n2sas
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54332
    url: https://127.0.0.1:54332
network-id: mitum
policy:
    threshold: 100
privatekey: L3Szj4t3w33YLsGFGeaB3v1vwae82yp5KWPcT7v1Y4WyQkAH7eCRmpr
publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
storage:
    blockdata:
        path: ./n2_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27019/n2_mc
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
nodes:
    - address: n0sas
      publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
      tls-insecure: true
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      tls-insecure: true
# n3 node(Suffrage node)

address: n3sas
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54333
    url: https://127.0.0.1:54333
network-id: mitum
policy:
    threshold: 100
privatekey: KwxfBSzwevSggJz2grf8FWrjvXzrctY3WismTy6GNdJpWXe5tF5Lmpr
publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
storage:
    blockdata:
        path: ./n3_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27020/n3_mc
suffrage:
    nodes:
        - n0sas
        - n1sas
        - n2sas
        - n3sas
nodes:
    - address: n0sas
      publickey: skRdC6GGufQ5YLwEipjtdaL2Zsgkxo3YCjp1B6w5V4bDmpu
      tls-insecure: true
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      tls-insecure: true
    - address: n2sas
      publickey: wfVsNvKaGbzB18hwix9L3CEyk5VM8GaogdRT4fD3Z6Zdmpu
      tls-insecure: true
# n4 node(Sync node)

address: n4sas
genesis-operations:
    - account-keys:
        keys:
            - publickey: rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu
              weight: 100
        threshold: 100
    currencies:
        - balance: "99999999999999999999"
          currency: MCC
    type: genesis-currencies
network:
    bind: https://0.0.0.0:54334
    url: https://127.0.0.1:54334
network-id: mitum
policy:
    threshold: 67
privatekey: KyKM3JtH8M9iBQrcFx4Lubi13Bg8pUPVYvxhihEfkiiqRRWYjjr4mpr
publickey: 2BQkVjJpMdx4BFEhfTtf1oTaG4nLN148Dfax3ZnWybA2bmpu
storage:
    blockdata:
        path: ./n4_data/blockfs
    database:
        uri: mongodb://127.0.0.1:27021/n4_mc
suffrage:
    nodes:
        - n1sas
        - n3sas
nodes:
    - address: n1sas
      publickey: ktJ4Lb6VcmjrbexhDdJBMnXPXfpGWnNijacdxD2SbvRMmpu
      url: https://127.0.0.1:54331
      tls-insecure: true
    - address: n3sas
      publickey: vAydAnFCHoYV6VDUhgToWaiVEtn5V4SXEFpSJVcTtRxbmpu
      url: https://127.0.0.1:54333
      tls-insecure: true
Node Discovery Scenario
다음은 Node Discovery 시나리오의 한 예제입니다.
case 0

All nodes are looking at each other
discoveries of n0: n1, n2
discoveries of n1: n0, n2
discoveries of n2: n0, n1
all joined
Node Discovery Case 0
case 1

All nodes are looking at the same node and only one node is looking at the other node.
discoveries of n0: n1
discoveries of n1: n0
discoveries of n2: n0
all joined
Node Discovery Case 0
case 2

All nodes are looking at each other.
discoveries of n0: n1
discoveries of n1: n2
discoveries of n2: n1
all joined
Node Discovery Case 0
case 3

One node is looking at no one, but another node is looking at it.
discoveries of n0: none
discoveries of n1: n2
discoveries of n2: n0
all joined
Node Discovery Case 0
case 4

A node sees no one, but no other nodes see it.
discoveries of n0: none
discoveries of n1: n2
discoveries of n2: n1
n1, n2: connected to each other
n0: disconnected
Node Discovery Case 0

Node Handover

node handover 과정을 설명합니다.

What is Handover?

Handover는 운용중인 노드를 멈추지 않고 교체하도록 도와줍니다.
  • 전체 네트워크에서 합의 과정에 참여하는 노드들은 여러 상황에 의해 교체되어야 할 수 있습니다.

  • 노드를 운용하던 프로그램이 업데이트 되어야 하는 경우, 다른 클라우드 서비스로 노드를 옮겨야 하는 경우, 노드가 실패하는 경우 등의 상황이 있을 수 있습니다. 그럴 때, 이미 운용중인 노드를 멈춤 없이 다른 대체 노드로 교체할 수 있습니다.

Handover는 향후 공개 네트워크를 지원할 수 있는 주요 특징 중 하나입니다.

Handover Scenario

  • Node A: 운용중인 노드

  • Node A-sub: 새롭게 교체될 대체 노드

  • Condition: A-subA 와 같은 구성을 가져야 합니다. 하지만, network.url 값은 달라야 합니다.

Node A’s Configuration
address: Asas
network-id: mitum
network:
    url: https://172.17.0.1:54321
privatekey: KyfqCLSEyfUhskZ63WtVH3m3pGgnurFHuTgkgu73Pgyjf8sxbp8Rmpr
Node A-sub’s Configuration
address: Asas
network-id: mitum
network:
    url: https://172.17.0.2:54321
privatekey: KyfqCLSEyfUhskZ63WtVH3m3pGgnurFHuTgkgu73Pgyjf8sxbp8Rmpr

How to Run

위 시나리오 하에 다음과 같은 순서로 진행됩니다.
  • A 는 suffrage 노드로서 운용되고 있으며 이를 A-sub 로 교체하려고 합니다.

  • ACONSENSUS 상태로 들어간 것을 확인한 후, 위 config를 사용한 node run 으로 A-sub 를 실행합니다.

  • A-sub 는 이전 블록 데이터를 수집하여 동기화를 수행하고 SYNCING 상태로 진입합니다.

  • A-subSYNCING 상태가 된 것을 확인하고, A-sub 노드에 대해 start-handover 를 실행합니다.

$ ./mitum node start-handover \
    "Asas" \
    "KyfqCLSEyfUhskZ63WtVH3m3pGgnurFHuTgkgu73Pgyjf8sxbp8Rmpr" \
    "mitum" \
    "https://172.17.0.2:54321"
  • B 가 동기화를 마칠 때 Handover 가 시작됩니다.

  • ACONSENSUS 에서 SYNCING 로 변경되며 A-subA 대신 합의 과정에 참여합니다.

  • 다른 suffrage 노드들은 A-subA 대신 suffrage 노드로 추가하며 함께 합의 과정을 수행합니다.

  • A 에 도달한 Operation seal이 다른 노드에도 전달됩니다.

What If a start-handover is sent to A after the Handover is over?
  • A-sub 로 교체된 ASYNCING 상태가 됩니다.

  • handover가 끝난 후, A 는 내부적으로 start-handover 명령 이전의 A-sub 의 상태와 같아집니다.

  • start-handover 명령어가 이 상태의 A 에 전달되면, 그 다음, AA-sub 를 교체하려고 시도합니다.

How can I check that the start-handover is finished?
  • A-subNodeInfo 를 확인하면 CONSENSUS 상태인 것을 확인할 수 있습니다.

  • ANodeInfo 가 확인되었을 때 SYNCING 상태라면 handover가 정상적으로 완료된 것입니다.

Command Line Interface

이 장에서 Mitum 및 Mitum 모델이 제공하는 명령어들과 그 사용 방법을 소개합니다.
기본 Mitum 프로그램이 제공하는 주요 명령어는 다음과 같습니다.
  • version

  • node

  • key

  • seal

  • storage

  • deploy

  • quic-client

Run 페이지를 거쳐왔다면 이미 node 명령어는 익숙할 것입니다.
각 모델의 operation은 seal 명령어를 통해 생성할 수 있습니다.
versionquic-client 를 사용하는 방법은 간단합니다. 각 명령어에 대해 하나씩 설명합니다.

Summary

예를 들어, 다음은 Mitum Currency가 제공하는 모든 명령어입니다.
특히 아래 명령어들은 Mitum Currency 모델을 확장한 모델에서만 사용가능합니다. 그 외 다른 명령어들은 일반적으로 모든 모델에서 사용가능합니다.
  • seal create-account

  • seal transfer

  • seal key-updater

  • seal currency-register

  • seal currency-policy-updater

  • seal suffrage-inflation

$ ./mitum --help

Usage: mitum-currency <command>

mitum-currency tool

Flags:
    -h, --help    Show context-sensitive help.

Commands:
    version                         version

    node                                node
        init                            initialize node
            <node design file>          node design file
        run                             run node
            <node design file>          node design file
        info                            node information
            <node url>                  remote mitum url
        start-handover                  start handover
            <node address>
            <private key of node>
            <network-id>
            <new node url>              new node url

    key                                 key
        new                             new keypair
        verify                          verify key
            <key>                       key
        address                         generate address from key
            [<threshold>]               threshold for keys (default: 100)
            [<key> ...]                 key for address (ex: "<public key>,<weight>")
        sign                            signature signing
            <privatekey>                privatekey
            <signature base>            signature base for signing

    seal                                seal
        send                            send seal to remote mitum node
            <privatekey>                privatekey for sign
        create-account                  create new account
            <privatekey>                privatekey to sign operation
            <sender>                    sender address
            <currency-amount> ...       amount (ex: "<currency>,<amount>")
        transfer                        transfer big
            <privatekey>                privatekey to sign operation
            <sender>                    sender address
            <receiver>                  receiver address
            <currency-amount> ...       amount (ex: "<currency>,<amount>")
        key-updater                     update keys
            <privatekey>                privatekey to sign operation
            <target>                    target address
            <currency>                  currency id
        currency-register               register new currency
            <privatekey>                privatekey to sign operation
            <currency-id>               currency id
            <genesis-amount>            genesis amount
            <genesis-account>           genesis-account address for genesis balance
        currency-policy-updater         update currency policy
            <privatekey>                privatekey to sign operation
            <currency-id>               currency id
        suffrage-inflation              suffrage inflation operation
            <privatekey>                privatekey to sign operation
            <inflation item> ...        ex: "<receiver address>,<currency>,<amount>"
        sign                            sign seal
            <privatekey>                sender's privatekey
        sign-fact                       sign facts of operation seal
            <privatekey>                sender's privatekey

    storage                             storage
        download                        download block data
            <data type>                 data type of block data,
                                        {manifest,operations,operations_tree,states,states_tree,init_voteproof,accept_voteproof,suffrage_info,proposal all}
            <height> ...                heights of block
        verify-blockdata                verify block data
            <blockdata path>
        verify-database                 verify database
            <database uri>
            <blockdata path>
        clean                           clean storage
            <node design file>          node design file
        clean-by-height                 clean storage by height
            <node design file>          node design file
            <height>                    height of block
        restore                         restore blocks from blockdata
            <node design file>          node design file
        set-blockdatamaps               set blockdatamaps
            <deploy key>
            <maps file>                 set blockdatamap file
            [<node url>]                remote mitum url; default: quic://localhost:54321

    deploy                              deploy
        key                             deploy key
            new                         request new deploy key
                <private key of node>
                <network-id>
                [<node url>]            remote mitum url; default: quic://localhost:54321
        keys                            deploy keys
            <private key of node>
            <network-id>
            [<node url>]                remote mitum url; default: quic://localhost:54321
        key                             deploy key
            <deploy key>
            <private key of node>
            <network-id>
            [<node url>]                remote mitum url; default: quic://localhost:54321
        revoke                          revoke deploy key
            <deploy key>
            <private key of node>
            <network-id>
            [<node url>]                remote mitum url; default: quic://localhost:54321

    quic-client                         quic-client
        <node url>                      remote mitum url

Run "mitum-currency <command> --help" for more information on a command.

Key Generation

key

key 는 키페어 생성, keys로부터 계정 주소 연산, 서명을 지원합니다.
key 의 하위 명령어는 다음과 같습니다.
  • new

  • address

  • sign

참고

Keypair

  • 개인키와 공개키는 키페어 생성에 의해 만들어집니다.

  • 생성된 키페어는 게정 생성, 노드의 키페어 등록, operation과 seal의 서명 생성에 사용됩니다.

new
new 를 사용해 새로운 키페어를 생성합니다.
Random Keypair
시드 없이 키페어를 생성합니다.
$ ./mitum key new
EXAMPLE
$ ./mitum key new
      hint: mpr
privatekey: L1ZERchoY53vC5TJQ3WnZEWmg97L2Utw5rgFrCwM7ekTu9zJkZYjmpr
 publickey: 28nFxuC5ETygieSGEYTkewwnCZseB4TNYGMRtxz31bvxzmpu
Keypair from Seed
시드로 키페어를 생성합니다. 문자열 시드의 길이는 36 이상이어야 합니다.
$ ./mitum key new --seed <string seed>
EXAMPLE
$ ./mitum key new --seed abcdefghijklmnopqrstuvwxyzABCDEFGHIJ
      hint: mpr
privatekey: KypAAGYtVFdTFLS8muPJhwfJBFCFHKSe594yYmKK3FPteh7sie4Dmpr
 publickey: 25BcZrcyiE3TD2BZEqkdDuaYB9zHxpdW82BNn8HkCLTijmpu
address
address 명령어로 keys로부터 주소를 계산합니다.
계정의 (public key, weight) 쌍과 threshold를 준비해야 합니다. 아래의 Multi Sig Account를 참고하세요.
$ ./mitum key address <threshold> [<publickey>,<weight>]
EXAMPLE
계정 정보가 아래와 같다고 가정합니다.

threshold

100

keys

{key: 21Sn1o…, weight: 50}, {key: utzCef…, weight: 50}

$ ./mitum key address 100 21Sn1owHXRx336aaerU1WbbKjiZXMcrJsnxBHP9etNx6zmpu,50 utzCefA1Szmmt3rAwqW5yEhxK1x3hG3Y3yThEK3gZmv3mpu,50
37x8YoAGA93B3HmDVNterRf1NTgz9tfN1gQn4jYuBYCHmca
하지만, key-updater 명령어로 계정의 key, weight, threshold 구성이 달라진 경우에는 올바른 계정 주소를 얻을 수 없습니다. key-updater 를 참고하세요.
Multi Sig Account
  • Mitum Currency에서 계정은 currency와 balance를 가진 데이터 구조체입니다.

  • 계정은 address라는 고유값을 가지고 있으며 이 값을 통해 식별할 수 있습니다.

  • 사용자의 Account authentication을 위해 공개키를 등록하세요.

  • Mitum Currency 계정은 multi signature가 가능하므로 multiple public keys를 가질 수 있습니다.

예를 들어, 다음 조건의 계정이 유효합니다.

address

HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

threshold

100

keys

{key: rd89Gx…, weight: 50}, {key: skRdC6…, weight: 50}

balance

{currency: MCC, amount: 10000}, {currency: MCC2, amount: 20000}

참고

각 계정이 따라야 할 조건은 다음과 같습니다.

  • threshold 의 범위는 1 <= threshold <= 100입니다.

  • weight 의 범위는 1 <= weight <= 100입니다.

  • 계정의 모든 weight 의 합은 threshold 이상이어야 합니다.

  • 각 공개키는 mpu 접미사가 붙은 BTC compressed public key여야 합니다.

  • 주소값에는 mca 가 접미사로 따라옵니다.

다음은 유효한 계정의 예시입니다.

CASE1 (single)

  • threshold: 100

  • keys: {key: rd89Gx…, weight: 100}

CASE2 (single)

  • threshold: 50

  • keys: {key: rd89Gx…, weight: 60}

CASE3 (multi)

  • threshold: 100

  • keys: {key: rd89Gx…, weight: 40}, {key: skRdC6…, weight: 30}, {key: mymMwq…, weight: 30}

CASE4 (multi)

  • threshold: 50

  • keys: {key: rd89Gx…, weight: 20}, {key: skRdC6…, weight: 20}, {key: mymMwq…, weight: 10}

같은 공개키 조합이라도 weightthreshold 의 조합이 다르면 다른 계정 주소를 가질 수 있습니다.

sign

sign 명령어로 특정 메시지에 개인키로 서명하세요.
$ ./mitum key sign <privatekey> <signature base>
EXAMPLE
$./mitum key sign L5nDx2QtZVBPtJvUQ13cj3bMhC487JdxrwXTdS6JgzTvnSHestCxmpr bWVzc2FnZQ=
381yXZHrm73kGD8z7FAksBjxy49wPRWn3WRdP22befdbFff6WYSdK8rz9TLpFWuEW7rmmphF3rHkrvTPvhVQ5kXNGLmELBwZ
signature base는 base64 인코딩된 문자열이어야 합니다.

Node Management

node

node 는 노드를 초기화하고 운용합니다.
node 의 하위 명령어는 다음과 같습니다.
  • init

  • run

  • start-handover

  • info

init
init 명령어로 노드 구성을 가지고 있는 노드 디자인 파일을 사용해 노드를 초기화하세요.
init command에 대한 자세한 설명은 node init 를 참고하세요.
$ ./mitum node init <node design file>
run
run 을 사용해 노드 구성을 가지고 있는 노드 디자인 파일에 따라 노드를 운용하세요.
See node run for a detailed explanation of run command.
$ ./mitum node run <node design file>
만약 노드가 suffrage 노드라면 다른 살아있는 suffrage 노드의 주소들을 Node discovery 프로토콜로 알아낼 수 있습니다. node discovery 특성은 노드가 suffrage 노드일 때만 제공됩니다.
  • suffrage 노드가 시작되면 publish url 정보를 제외한 모든 suffrage 노드들의 네트워크 정보를 결정하는 것이 가능합니다.

  • node discovery를 위해 노드는 시작 시 discovery url에 하나 이상의 suffrage 노드의 주소를 설정해야 합니다.

discovery url을 설정하기 위해 –discovery 명령줄 옵션을 사용하세요.
$ ./mitum node run <n0 config file> --discovery <n1 publish url> --discovery <n2 publish url>
  • 노드가 discovery url을 스스로 설정하지 않더라도 다른 suffrage 노드가 이 노드를 discovery 노드로 지정하면 다른 노드들의 publish url은 gossip protocol에 의해 알려집니다. 만약 discovery로 지정된 노드들이 discovery 운용중이지 않다면, 성공할때까지 시도합니다.

  • 또한 node discovery는 suffrage 노드와만 작동합니다. suffrage 노드 리스트에 추가되지 않은 노드들은 다른 suffrage 노드들의 url들을 노드 설정에 지정합니다.

  • 만약 log level를 info로 설정하면 쉽게 새롭게 생성되는 블록의 정보를 확인할 수 있습니다.

–log 명령줄 옵션은 특정 파일들에 로그를 수집할 수 있습니다.
Mitum은 다음과 같은 quic (http) 요청 메시지를 포함한 방대한 디버깅 로그 메시지를 덤프합니다.
"l":"debug","module":"http2-server","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15","req_id":"c30q3kqciaejf9nj79c0","status":200,"size":2038,"duration":0.541625,"content-length":0,"content-type":"","headers":{"Accept-Language":["en-us"],"Connection":["keep-alive"],"Upgrade-Insecure-Requests":["1"]},"host":"127.0.0.1:54320","method":"GET","proto":"HTTP/1.1","remote":"127.0.0.1:55617","url":"/","t":"2021-06-10T05:23:31.030086621Z","caller":"/Users/soonkukkang/go/pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210609043008-298f37780037/network/http.go:61","m":"request"
–network-log 명령줄 옵션은 특정 파일들에 이 요청 메시지들을 수집할 수 있습니다.
$ ./mitum node run \
    --log-level debug \
    --log-format json \
    --log ./mitum.log \
    --network-log ./mitum-request.log \
    ./tutorial.yml
여러 파일을 ``–network-log``와 ``–log``로 설정할 수 있습니다.
–network-log 옵션은 digest API(http2)로부터 요청 로그를 수집할 것입니다.
–network-log 옵션은 오직 node run 명령어와 함께 사용될 수 있습니다.
start-handover
start-handover 명령어로 운용중인 노드를 다른 노드로 교체하세요.
start-handover 에 대한 자세한 설명은 Node Handover 를 확인하세요.
$ ./mitum node start-handover <node address> <private key of node> <network-id> <new node url>
info
info 명령어로 노드 url을 사용해 원격 노드 정보를 확인하세요.
$ ./mitum node info <node url>
EXAMPLE
$ ./mitum node info https://127.0.0.1:54321 --tls-insecure --pretty
{
    "_hint": "mitum-currency-node-info-v0.0.1",
    "node": {
        "_hint": "base-node-v0.0.1",
        "address": "mc-nodesas",
        "publickey": "27P4S2FdDALmg4QzShCDTDne1pe8y1H2bE2uQCVpnqWpumpu",
        "url": "https://127.0.0.1:54321"
    },
    "network_id": "bWl0dW0=",
    "state": "CONSENSUS",
    "last_block": {
        "_hint": "block-manifest-v0.0.1",
        "hash": "5Z2SFA6DqYg8KdRPAD4uXAM7wpPE6vjyQ5iWqu4sc1yP",
        "height": 421,
        "round": 0,
        "proposal": "3H5wmRqvnburtEMqvkLh11vetbbdsdvHAkJRM6L6nu3Z",
        "previous_block": "J3if3xYD1wUQxUnm52UpddHT4Dipsd35bYGQxurMGnXm",
        "block_operations": null,
        "block_states": null,
        "confirmed_at": "2021-06-10T07:04:31.378699784Z",
        "created_at": "2021-06-10T07:04:31.390856784Z"
    },
    "version": "v0.0.0",
    "url": "https://127.0.0.1:54321",
    "policy": {
        "network_connection_timeout": 3000000000,
        "max_operations_in_seal": 10,
        "max_operations_in_proposal": 100,
        "interval_broadcasting_init_ballot": 1000000000,
        "wait_broadcasting_accept_ballot": 1000000000,
        "threshold": 100,
        "interval_broadcasting_accept_ballot": 1000000000,
        "timeout_waiting_proposal": 5000000000,
        "timespan_valid_ballot": 60000000000,
        "interval_broadcasting_proposal": 1000000000,
        "suffrage": "{\"type\":\"\",\"cache_size\":10,\"number_of_acting\":1}"
    },
    "suffrage": [
        {
            "_hint": "base-node-v0.0.1",
            "address": "mc-nodesas",
            "publickey": "27P4S2FdDALmg4QzShCDTDne1pe8y1H2bE2uQCVpnqWpumpu",
            "url": "https://127.0.0.1:54321"
        }
    ]
}

storage

storage 명령어는 블록 데이터의 내려받기, 검증, 복구를 도와줍니다.
storage 의 하위 명령어는 다음과 같습니다.
  • download

  • verify-blockdata

  • verify-database

  • clean

  • clean-by-height

  • restore

  • set-blockdatamaps

download
download 를 통해 특정 block height의 블록 데이터를 내려받으세요.
$ ./mitum storage download --node=quic://localhost:54321 <data type> <height> ...
EXAMPLE
$ ./mitum storage download --tls-insecure --node=https://127.0.0.1:54321  --save=data all -- -1 0 1 2 3 4 5
2021-06-08T10:50:08.018561Z INF saved file=data/000/000/000/000/000/000/0_1/-1-manifest-48cfbadd18b892bfd0a6fa230ff0c5f719bd517d37f594012aeca7244ef12599.jsonld.gz height=-1 module=command-block-download
2021-06-08T10:50:08.018531Z INF saved file=data/000/000/000/000/000/000/000/0-manifest-307ffa78d4ce5e32e25347f5ec8ee626e44d41e55f565c2082ac00f8f128dbd9.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.058628Z INF saved file=data/000/000/000/000/000/000/0_1/-1-operations-0fedf0c3ccb08aea5694e04a382ca04fb1338dfc9c2c408fe6296c93c0931124.jsonld.gz height=-1 module=command-block-download
2021-06-08T10:50:08.068871Z INF saved file=data/000/000/000/000/000/000/000/0-operations-d17d5b941aec3c100a43e2c228bca4134473bb9c78dcf567bdd8b9e12e5cc928.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.12423Z INF saved file=data/000/000/000/000/000/000/000/0-operations_tree-45aff89f7084384fdecfac9689b75168a33f03bf6ba677ad085a6ac8fdf2bd12.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.130027Z INF saved file=data/000/000/000/000/000/000/0_1/-1-operations_tree-d0c45c5292593853052aba6d3f410c93f6cc4473e7873ded2d623069adfc0025.jsonld.gz height=-1 module=command-block-download
2021-06-08T10:50:08.162735Z INF saved file=data/000/000/000/000/000/000/000/0-states-73ac164e67fb49877b132aaaae2f7adf92cc237ef0e63db30f3013c283fb7100.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.172536Z INF saved file=data/000/000/000/000/000/000/0_1/-1-states-0fedf0c3ccb08aea5694e04a382ca04fb1338dfc9c2c408fe6296c93c0931124.jsonld.gz height=-1 module=command-block-download
2021-06-08T10:50:08.215233Z INF saved file=data/000/000/000/000/000/000/000/0-states_tree-7155e9c9f393943429f9341f22cba749203eaa2effd51bbbdb9b97c899cac62e.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.217385Z INF saved file=data/000/000/000/000/000/000/0_1/-1-states_tree-d0c45c5292593853052aba6d3f410c93f6cc4473e7873ded2d623069adfc0025.jsonld.gz height=-1 module=command-block-download
2021-06-08T10:50:08.278019Z INF saved file=data/000/000/000/000/000/000/000/0-init_voteproof-dab53369d715fc74ad750d95f1ceb859d62009165a76ea3368399da2b16bf4d7.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.287794Z INF saved file=data/000/000/000/000/000/000/0_1/-1-init_voteproof-812c550f7595c4c949d2255217a343864bdd878b09d124235d7db07758620bc7.jsonld.gz height=-1 module=command-block-download
2021-06-08T10:50:08.319642Z INF saved file=data/000/000/000/000/000/000/000/0-accept_voteproof-09fd08050476a5d0a343154aaa0325809d721004b49cba303a58300b7415235e.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.334284Z INF saved file=data/000/000/000/000/000/000/0_1/-1-accept_voteproof-812c550f7595c4c949d2255217a343864bdd878b09d124235d7db07758620bc7.jsonld.gz height=-1 module=command-block-download
2021-06-08T10:50:08.399426Z INF saved file=data/000/000/000/000/000/000/000/0-suffrage_info-038aa59ed7db04c96d11405336c7a2d1cb8ad6df5a18d66f8f3bf2919c6767f8.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.591648Z INF saved file=data/000/000/000/000/000/000/0_1/-1-suffrage_info-038aa59ed7db04c96d11405336c7a2d1cb8ad6df5a18d66f8f3bf2919c6767f8.jsonld.gz height=-1 module=command-block-download
2021-06-08T10:50:08.613875Z INF saved file=data/000/000/000/000/000/000/000/0-proposal-81c03f9c912591796ae5f3dbaab85bc91d7ca4031413787abb3068c5efa78360.jsonld.gz height=0 module=command-block-download
2021-06-08T10:50:08.750795Z INF saved file=data/000/000/000/000/000/000/0_1/-1-proposal-812c550f7595c4c949d2255217a343864bdd878b09d124235d7db07758620bc7.jsonld.gz height=-1 module=command-block-download
map
download map 을 사용해 blockdata map을 내려받으세요.
자세한 내용은 Block Data 을 참고하세요.
$ ./mitum storage download map --node=https://localhost:54321 <height> ...
EXAMPLE
$ ./mitum storage download map --tls-insecure --node=https://127.0.0.1:54321 0 --pretty
{
    "_hint": "base-blockdatamap-v0.0.1",
    "hash": "DvYK11jZ8KWafAGPssypdNMRwwXwJJTKeyzTAx4JNnwc",
    "height": 10,
    "block": "AnjD39fpP6cJKVhnSfJxPfQ8sxrVwCrKhm1zWjb38dUS",
    "created_at": "2021-06-10T06:37:42.251Z",
    "items": {
        "accept_voteproof": {
        "type": "accept_voteproof",
        "checksum": "03dd3c2ce852729ff52ec7dcd31a2a1532656fbcea12a28438c3e84c8146c753",
        "url": "file:///000/000/000/000/000/000/010/10-accept_voteproof-03dd3c2ce852729ff52ec7dcd31a2a1532656fbcea12a28438c3e84c8146c753.jsonld.gz"
        },
        "init_voteproof": {
        "type": "init_voteproof",
        "checksum": "70d59dc3e84ddd06d319e9d38d68a976b09a816fbe5a5fdef42f5b80908b0fa0",
        "url": "file:///000/000/000/000/000/000/010/10-init_voteproof-70d59dc3e84ddd06d319e9d38d68a976b09a816fbe5a5fdef42f5b80908b0fa0.jsonld.gz"
        },
        "states": {
        "type": "states",
        "checksum": "d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59",
        "url": "file:///000/000/000/000/000/000/010/10-states-d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59.jsonld.gz"
        },
        "proposal": {
        "type": "proposal",
        "checksum": "ccd31f6627aa3cc6e9768b318f8cfd8e7f371b907f329fb89d692c7aea2ef465",
        "url": "file:///000/000/000/000/000/000/010/10-proposal-ccd31f6627aa3cc6e9768b318f8cfd8e7f371b907f329fb89d692c7aea2ef465.jsonld.gz"
        },
        "suffrage_info": {
        "type": "suffrage_info",
        "checksum": "f8955c57fb4a7dc48e71973af01852008c76ae4bb5487f8d6fccebcc10e5412e",
        "url": "file:///000/000/000/000/000/000/010/10-suffrage_info-f8955c57fb4a7dc48e71973af01852008c76ae4bb5487f8d6fccebcc10e5412e.jsonld.gz"
        },
        "manifest": {
        "type": "manifest",
        "checksum": "1f21552b0d7a11c0397c7429849a0f611d9681f70cecd5165e21fcbd5276a880",
        "url": "file:///000/000/000/000/000/000/010/10-manifest-1f21552b0d7a11c0397c7429849a0f611d9681f70cecd5165e21fcbd5276a880.jsonld.gz"
        },
        "operations": {
        "type": "operations",
        "checksum": "d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59",
        "url": "file:///000/000/000/000/000/000/010/10-operations-d890f3ba40375a6b2d331883907dc0a9ca980ce45f7d5dcaca9087278c0b6d59.jsonld.gz"
        },
        "states_tree": {
        "type": "states_tree",
        "checksum": "1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26",
        "url": "file:///000/000/000/000/000/000/010/10-states_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz"
        },
        "operations_tree": {
        "type": "operations_tree",
        "checksum": "1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26",
        "url": "file:///000/000/000/000/000/000/010/10-operations_tree-1f9877aebf8854fd42154c6e6479ff6a3e379b2762c65995c80f3dff2a357a26.jsonld.gz"
        }
    },
    "writer": "blockdata-writer-v0.0.1"
}
verify-blockdata
verify-blockdata 을 사용해 로컬 스토리지의 블록 데이터를 검증하세요.
$ ./mitum storage verify-blockdata <blockdata path>
EXAMPLE
$ ./mitum storage verify-blockdata data --network-id=mitum --verbose
2021-06-08T10:52:03.249204Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/cmd.go:86 > maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined module=command-blockdata-verify
2021-06-08T10:52:03.250015Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/cmd.go:95 > flags parsed flags={"CPUProf":"mitum-cpu.pprof","EnableProfiling":false,"LogColor":false,"LogFile":null,"LogFormat":"terminal","LogLevel":"info","LogOutput":{},"MemProf":"mitum-mem.pprof","NetworkID":"bWl0dW0=","Path":"data","TraceProf":"mitum-trace.pprof","Verbose":true} module=command-blockdata-verify
2021-06-08T10:52:03.250188Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:38 > trying to verify blockdata module=command-blockdata-verify path=data
2021-06-08T10:52:03.250315Z INF ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:107 > last height found last_height=5 module=command-blockdata-verify
2021-06-08T10:52:03.250607Z INF ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/verify_storage.go:53 > checking manifests module=command-blockdata-verify
2021-06-08T10:52:03.255675Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/verify_storage.go:109 > manifests loaded heights=[-1,6] module=command-blockdata-verify
2021-06-08T10:52:03.255766Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/verify_storage.go:121 > manifests checked heights=[-1,6] module=command-blockdata-verify
2021-06-08T10:52:03.258293Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:257 > block data files checked height=0 module=command-blockdata-verify
2021-06-08T10:52:03.257947Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:257 > block data files checked height=1 module=command-blockdata-verify
2021-06-08T10:52:03.259131Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:257 > block data files checked height=4 module=command-blockdata-verify
2021-06-08T10:52:03.257772Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:257 > block data files checked height=5 module=command-blockdata-verify
2021-06-08T10:52:03.260384Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:257 > block data files checked height=2 module=command-blockdata-verify
2021-06-08T10:52:03.260419Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:257 > block data files checked height=-1 module=command-blockdata-verify
2021-06-08T10:52:03.260606Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:257 > block data files checked height=3 module=command-blockdata-verify
2021-06-08T10:52:03.274069Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:187 > block checked height=-1 module=command-blockdata-verify
2021-06-08T10:52:03.279165Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:187 > block checked height=3 module=command-blockdata-verify
2021-06-08T10:52:03.279179Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:187 > block checked height=2 module=command-blockdata-verify
2021-06-08T10:52:03.279223Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:187 > block checked height=1 module=command-blockdata-verify
2021-06-08T10:52:03.279267Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:187 > block checked height=4 module=command-blockdata-verify
2021-06-08T10:52:03.279344Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:187 > block checked height=5 module=command-blockdata-verify
2021-06-08T10:52:03.281481Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:187 > block checked height=0 module=command-blockdata-verify
2021-06-08T10:52:03.281569Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/blockdata_verify.go:87 > blockdata verified module=command-blockdata-verify
.....
verify-database
verify-database 명령어는 블록데이터와의 비교를 통해 database를 검증합니다.
$ ./mitum storage verify-database <database uri> <blockdata path>
EXAMPLE
$ ./mitum storage verify-database mongodb://127.0.0.1:27017/n0_mc blockfs --network-id=mitum --verbose
2021-06-08T10:56:20.879671Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/cmd.go:86 > maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined module=command-database-verify
2021-06-08T10:56:20.879921Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/cmd.go:95 > flags parsed flags={"CPUProf":"mitum-cpu.pprof","EnableProfiling":false,"LogColor":false,"LogFile":null,"LogFormat":"terminal","LogLevel":"info","LogOutput":{},"MemProf":"mitum-mem.pprof","NetworkID":"bWl0dW0=","Path":"data","TraceProf":"mitum-trace.pprof","URI":"mongodb://127.0.0.1:27017/mc","Verbose":true} module=command-database-verify
2021-06-08T10:56:20.880018Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:310 > processed from_process= module=process-manager process=init
2021-06-08T10:56:20.880066Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:310 > processed from_process=time-syncer module=process-manager process=config
2021-06-08T10:56:21.038454Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/util/localtime/time_sync.go:67 > started interval=120000 module=time-syncer server=time.google.com
2021-06-08T10:56:21.042330408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:310 > processed from_process=init module=process-manager process=time-syncer
2021-06-08T10:56:21.042835408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:359 > hook processed from=encoders hook=add_hinters module=process-manager
2021-06-08T10:56:21.042884408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:310 > processed from_process=init module=process-manager process=encoders
2021-06-08T10:56:21.203404408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:310 > processed from_process=init module=process-manager process=database
2021-06-08T10:56:21.203608408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:359 > hook processed from=blockdata hook=check_blockdata_path module=process-manager
2021-06-08T10:56:21.203899408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/database_verify.go:207 > block found block={"hash":"CzF6t6ePyBaz6RnSjw6YRhwKsxA5sRnhHwQJvK8xVgMR","height":0,"round":0} module=command-database-verify
2021-06-08T10:56:21.204001408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:359 > hook processed from=blockdata hook=check_storage module=process-manager
2021-06-08T10:56:21.204054408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/pm/processes.go:310 > processed from_process=init module=process-manager process=blockdata
2021-06-08T10:56:21.204357408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/database_verify.go:74 > trying to verify database module=command-database-verify path=data uri=mongodb://127.0.0.1:27017/mc
2021-06-08T10:56:21.204424408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/database_verify.go:100 > verifying database module=command-database-verify
2021-06-08T10:56:21.204941408Z INF ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/verify_storage.go:53 > checking manifests module=command-database-verify
2021-06-08T10:56:21.210215408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/verify_storage.go:109 > manifests loaded heights=[-1,1] module=command-database-verify
2021-06-08T10:56:21.210355408Z DBG ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/verify_storage.go:121 > manifests checked heights=[-1,1] module=command-database-verify
2021-06-08T10:56:21.210456408Z INF ../../../../pkg/mod/github.com/spikeekips/mitum@v0.0.0-20210605063447-f720096b150d/launch/cmds/database_verify.go:105 > database verified module=command-database-verify
clean
clean 명령어는 블록데이터와 데이터베이스를 정리합니다.
$ ./mitum storage clean <node design file>
EXAMPLE
$ ./mitum storage clean node.yml
clean-by-height
clean-by-height 는 특정 height 위로 블록데이터와 데이터베이스를 정리합니다.
$ ./mitum storage clean-by-height <node design file> <height>
EXAMPLE
$ ./mitum storage clean-by-height node.yml 54234
restore
restore 명령어로 내려받은 블록데이터로부터 전체 데이터베이스를 복구하세요.
restore 사용 시, 블록데이터 뿐만 아니라 digest API에 사용되는 데이터도 생성됩니다. yml 파일 설정의 network id 이 내려받은 노드의 것과 같은지 확인하세요.
  • –concurrency 옵션으로 여러 개의 블록 데이터가 동시에 복구될 수 있습니다.

  • 존재하는 mongodb 데이터를 삭제하고 복구하고 싶다면 –clean 을 사용하세요.

  • 실제 복구하지 않고 오직 blockdata를 확인하려면 –dryrun 를 사용하세요.

  • –one 옵션으로 특정 blockdata 디렉토리를 특정하면, 그것들을 하나씩 복구할 수 있습니다.

$ ./mitum storage restore <node design file>
EXAMPLE
$ ./mitum storage restore node.yml --concurrency 10
2021-06-08T11:00:34.304594Z INF prepare to run module=command-restore
2021-06-08T11:00:34.304656Z INF prepared module=command-restore
2021-06-08T11:00:34.743477729Z INF block restored height=-1 module=command-restore
2021-06-08T11:00:34.828859729Z INF block restored height=0 module=command-restore
2021-06-08T11:00:34.829060729Z INF restored module=command-restore
2021-06-08T11:00:35.833206729Z INF stopped module=command-restore
set-blockdatamaps
set-blockdatamaps 는 여러 BlockDataMap을 업데이트합니다.
자세한 내용은 Block Data 를 참고하세요.
$ ./mitum storage set-blockdatamaps <deploy key> <maps file> [<node url>]

deploy

노드의 deploy key를 생성하고 관리하기 위해 deploy key 를 사용하세요.
deploy key 의 하위 명령어는 다음과 같습니다.
  • new

  • keys

  • key

  • revoke

참고

What is deploy key?

(BlockDataMap 변경과 같은)노드의 업데이트는 반드시 노드 소유자에 의해 허용되어야 합니다. 노드 소유자는 노드를 관리할 때 자신을 증명하기 위한 key를 사용합니다.

하지만 노드 관리에 노드의 개인키를 직접 사용하는 것은 위험할 수 있습니다. 따라서 우리는 노드 관리 등을 위한 교체 가능하고 관리 가능한 키가 필요합니다.

deploy key 는 이런 목적으로 사용됩니다.

new
new 를 사용해 새로운 deploy key를 생성하고 노드에 등록하세요.
$ ./mitum deploy key new <private key of node> <network-id> [<node url>]
EXAMPLE
$ NODE_PRV_KEY=KxaTHDAQnmFeWWik5MqWXBYkhvp5EpWbsZzXeHDdTDb5NE1dVw8wmpr

$ NODE=https://127.0.0.1:54321

$ NETWORK_ID=mitum

$ ./mitum deploy key new $NODE_PRV_KEY $NETWORK_ID $NODE --tls-insecure
{"key":"d-fc4179e7-2ff3-4372-bd83-f70526bed476","added_at":"2021-06-09T09:31:22.321675852Z"}
2021-06-09T09:31:22.320055Z INF new deploy key module=command-deploy-key-new
keys
keys 를 사용해 노드에 등록된 deploy key 리스트를 확인하세요.
$ ./mitum deploy key keys <private key of node> <network-id> [<node url>]
EXAMPLE
$ NODE_PRV_KEY=KxaTHDAQnmFeWWik5MqWXBYkhvp5EpWbsZzXeHDdTDb5NE1dVw8wmpr

$ NODE=https://127.0.0.1:54321

$ NETWORK_ID=mitum

$ ./mitum deploy key keys $NODE_PRV_KEY $NETWORK_ID $NODE --tls-insecure
[{"key":"d-974702df-89a7-4fd1-a742-2d66c1ead6cd","added_at":"2021-06-09T03:14:33.9Z"},{"key":"d-2897ced4-ceb5-4e11-be81-3139350c9c55","added_at":"2021-06-09T03:56:49.393Z"},{"key":"d-fc4179e7-2ff3-4372-bd83-f70526bed476","added_at":"2021-06-09T09:31:22.321675852Z"}]
key
key 를 사용해 노드에 deploy key가 존재하는지 확인하세요.
$ ./mitum deploy key key <deploy key> <private key of node> <network-id> [<node url>]
EXAMPLE
$ NODE_PRV_KEY=KxaTHDAQnmFeWWik5MqWXBYkhvp5EpWbsZzXeHDdTDb5NE1dVw8wmpr

$ NODE=https://127.0.0.1:54321

$ NETWORK_ID=mitum

$ DEPLOY_KEY=d-974702df-89a7-4fd1-a742-2d66c1ead6cd

$ ./mitum deploy key $DEPLOY_KEY $NODE_PRV_KEY $NETWORK_ID $NODE --tls-insecure
{"key":"d-974702df-89a7-4fd1-a742-2d66c1ead6cd","added_at":"2021-06-09T03:14:33.9Z"}
revoke
revoke 를 사용해 노드에서 deploy key를 취소하세요.
$ ./mitum deploy key revoke <deploy key> <private key of node> <network-id> [<node url>]
EXAMPLE
$ NODE_PRV_KEY=KxaTHDAQnmFeWWik5MqWXBYkhvp5EpWbsZzXeHDdTDb5NE1dVw8wmpr

$ NODE=https://127.0.0.1:54321

$ NETWORK_ID=mitum

$ DEPLOY_KEY=d-974702df-89a7-4fd1-a742-2d66c1ead6cd

$ ./mitum deploy key revoke $DEPLOY_KEY $NODE_PRV_KEY $NETWORK_ID $NODE --tls-insecure
2021-06-09T09:36:19.763339Z INF deploy key revoked deploy_key=d-974702df-89a7-4fd1-a742-2d66c1ead6cd module=command-deploy-key-revoke

version

version 을 사용해 Mitum Currency의 버전을 확인하세요.
$ ./mitum version
EXAMPLE
$ ./mitum version
v0.0.1

quic-client

quic-client 의 응답은 API의 node info 응답과 형태가 같습니다.
$ ./mitum quic-client <node-url>
EXAMPLE
$ ./mitum quic-client https://3.35.171.179:54321/
{
    "_hint": "node-info-v0.0.1",
    "node": {
        "_hint": "base-node-v0.0.1",
        "address": "node4sas",
        "publickey": "21im86HvT3aC4p23AExN7PKRD3RF1GR8cD3E95iEJHhNKmpu"
    },
    "network_id": "bWl0dW0=",
    "state": "CONSENSUS",
    "last_block": {
        "_hint": "block-manifest-v0.0.1",
        "hash": "GBQqKbR6pAs8gWzNmf5mrHGUYUmjs829NVX4WuYz7uzf",
        "height": 994024,
        "round": 0,
        "proposal": "HbxL38mNX8NGTqErNE3Hw5w639qKpbEwC4SkkCDZvrYB",
        "previous_block": "5rPQHEunbAw15YG3GaZneYKQpxsKRgQuThW6Yd7KBZb",
        "block_operations": null,
        "block_states": null,
        "confirmed_at": "2022-01-19T05:58:14.623577286Z",
        "created_at": "2022-01-19T05:58:14.631963244Z"
    },
    "version": "v0.0.1-stable-383cf0c-20211224",
    "policy": {
        "timespan_valid_ballot": 60000000000,
        "network_connection_timeout": 3000000000,
        "threshold": 100,
        "max_operations_in_seal": 10,
        "max_operations_in_proposal": 100,
        "interval_broadcasting_proposal": 1000000000,
        "wait_broadcasting_accept_ballot": 1000000000,
        "timeout_waiting_proposal": 5000000000,
        "interval_broadcasting_init_ballot": 1000000000,
        "interval_broadcasting_accept_ballot": 1000000000,
        "suffrage": "{\"type\":\"\",\"cache_size\":10,\"number_of_acting\":1}"
    },
    "suffrage": [
        {
            "address": "node4sas",
            "publickey": "21im86HvT3aC4p23AExN7PKRD3RF1GR8cD3E95iEJHhNKmpu",
            "conninfo": {
                "_hint": "http-conninfo-v0.0.1",
                "url": "https://3.35.171.179:54321",
                "insecure": true
            }
        }
    ],
    "conninfo": {
        "_hint": "http-conninfo-v0.0.1",
        "url": "https://3.35.171.179:54321",
        "insecure": true
    }
}

Seal Command

seal 은 seal에 포함된 다양한 operation들을 실행하는데 도움을 주는 명령어입니다.
operation과 관련된 명령어는 다음과 같습니다.
  • create-account

  • transfer

  • key-updater

  • currency-register

  • currency-policy-updater

  • suffrage-inflation

``seal``은 서명을 만들고 seal을 전송하도록 지원합니다.
signature generation과 transmission에 관련된 명령어는 다음과 같습니다.
  • send

  • sign

  • sign-fact

operation이 제대로 처리되었는지는 api를 통해 확인할 수 있습니다.
더 많은 정보는 Confirming the Success of the Operation 를 참고하세요.

send

send 명령어를 통해 seal을 전송하세요.
$ ./mitum seal send  <sender privatekey> --network-id=<network id> --seal=<data file path> --node=<node https url>
Mitum Currency에서 생성된 operation들은 seal 단위로 전송됩니다.
seal을 전송하기 위해 서명이 필요합니다. 서명 생성 시 필요한 키페어와 관련된 것은 Seal 를 참고하세요.
EXAMPLE
data.json은 json으로 작성된 seal 파일입니다.
$ NETWORK_ID="mitum"

$ NODE="https://127.0.0.1:54321"

$ AC0_PRV=L1jPsE8Sjo5QerUHJUZNRqdH1ctxTWzc1ue8Zp2mtpieNwtCKsNZmpr

$ ./mitum seal send --network-id=$NETWORK_ID $AC0_PRV --seal=data.json --node=$NODE jq -R '. as $line | try fromjson catch $line'
{
    "_hint": "seal-v0.0.1",
    "hash": "6nLRWj5hGQ7va9gxpAJCBxNDKvgFnms9jaa913uWgsx1",
    "body_hash": "32ZEf8V9fV41JHVWbbqQdYWtrw5T255XN8fSXhBAhGFD",
    "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
    "signature": "381yXZ4LFY5HnK211gpG3W22V52vMLqix4SysXEeMnqcXUk5eEYGM1JfFaX5UE86EF6qog5jUScPqZo6UkiaAFocUhwtSsjx",
    "signed_at": "2021-06-10T09:17:51.236729Z",
    "operations": [
        {
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "7YvcA6WAcKEag1Z4Jv1bQ2wYxAZix5sNB6u8MUXDM44D",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "3equMRJAVHk8WdVanffzEWkHfwnBDqF2cFwmmcv8MzDW",
                "token": "MjAyMS0wNi0xMFQwOToxNzo1MS4yMDgwOTVa",
                "sender": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "100000",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
                    "signature": "AN1rKvtPEX4MRu6kWRYDJ6WtsSnwxwJsYXiVi2Qujx8sF6SJzsZZKj7anCd9cmUZ175FSYLkkWkpDRj3fVgZFDxLFSnos3szz",
                    "signed_at": "2021-06-10T09:17:51.211816Z"
                }
            ],
            "memo": ""
        }
    ]
}
2021-06-10T09:17:51.240066Z INF trying to send seal module=command-send-seal
2021-06-10T09:17:51.345243Z INF sent seal module=command-send-seal
테스트를 위해 로컬 노드로 전송할 때, tls 인증과 관련한 에러가 발생할 수 있습니다.
이 경우, seal 전송 시 –tls-insecure=true 옵션을 추가하세요.
$ ./mitum seal send --network-id=$NETWORK_ID $AC0_PRV --tls-insecure=true --seal=data.json --node=$NODE

sign

sign 으로 seal에 서명하세요.
$ ./mitum seal sign --network-id=NETWORK-ID-FLAG <privatekey>
EXAMPLE
sign 사용 전, 서명 생성을 위해 opeation이 들어있는 seal의 json 파일을 준비하세요.
예를 들어,
{
    "_hint": "seal-v0.0.1",
    "hash": "5W39B2mmtc4KK9THiRdoF6F5UMZPSxjzedPePojVhqyV",
    "body_hash": "5yGtCzJiPRRbZkeLawQev4dvdYgYuKHXe6TP6x2VLSt4",
    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
    "signature": "381yXZHsyzbc8qTD7BJgmGoM8ncSrUcyDZiSNanARp9h84tvcj6HkGXzpFyck9arJTCQDmPGzT5UFq1coHv7wijusgynSfgr",
    "signed_at": "2021-06-10T06:50:26.903245Z",
    "operations": [
        {
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "9mFHaqd66pv7RjoAbKScUucJLKW7KVSkWqN1WXnzMrxQ",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "3CpL1MgD1TPejUmVxPKSgiUu6LCR7FhFrDehSjSogavZ",
                "token": "MjAyMS0wNi0xMFQwNjo1MDoyNi44NzQyNzVa",
                "sender": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "Dut3WiprEo1BRcx2xRvh6qbBgxaTLXQDris7SihDTET8",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "27tMvbSpajF1VSnrn3xRQESpPAsmA7KZEfUz9ZuTZEemumpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "100000",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                    "signature": "AN1rKvtfRrgY15owfURsNyfWnYtZ7syuRafWa637tkWB1HyxDCD2tWZUhySTg6mnZWQKpP3i6Dmf96fw9TUWb8rrbsetHJciH",
                    "signed_at": "2021-06-10T06:50:26.877954Z"
                }
            ],
            "memo": ""
        }
    ]
}
이 json 파일과 함께 seal sign 을 실행하세요.
그러면 새로운 seal 서명이 추가된 seal을 얻을 수 있습니다.
$ SIGNER_PRV=KxmWM4Zj5Ln8bbDwVZEKrYQY8N51Uk3UVq5GNQAeb2KW8JqHmsgmmpr
$ ./mitum seal sign --seal=data.json  --network-id=mitum $SIGNER_PRV --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "5dLCySkPrFtc8SnbjzELBK5GR7VQocrK7cXswEnhEa1S",
    "body_hash": "3Ah7J2q4HhFXSgV3c4EQWeZtpi1nFY7be2nmL4X6qDxa",
    "signer": "224ekkhrax6EpekzfLTv9See1hNDZW3LAjWBRuzTMpgnrmpu",
    "signature": "AN1rKvtFhZfDzyLLXtK3PtZ8P1jSTqZy6gC8WooBjWRhzwLrXjCcVTeo4juzdMg83he2emJ3SVkCNZssiB1pTtAPtx753P5CT",
    "signed_at": "2021-06-10T07:12:41.992205Z",
    "operations": [
        {
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "9mFHaqd66pv7RjoAbKScUucJLKW7KVSkWqN1WXnzMrxQ",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "3CpL1MgD1TPejUmVxPKSgiUu6LCR7FhFrDehSjSogavZ",
                "token": "MjAyMS0wNi0xMFQwNjo1MDoyNi44NzQyNzVa",
                "sender": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "Dut3WiprEo1BRcx2xRvh6qbBgxaTLXQDris7SihDTET8",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "27tMvbSpajF1VSnrn3xRQESpPAsmA7KZEfUz9ZuTZEemumpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                            "_hint": "mitum-currency-amount-v0.0.1",
                            "amount": "100000",
                            "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                    "signature": "AN1rKvtfRrgY15owfURsNyfWnYtZ7syuRafWa637tkWB1HyxDCD2tWZUhySTg6mnZWQKpP3i6Dmf96fw9TUWb8rrbsetHJciH",
                    "signed_at": "2021-06-10T06:50:26.877954Z"
                }
            ],
            "memo": ""
        }
    ]
}

sign-fact

sign-fact 를 사용해 opeation fact에 서명을 추가하세요.
이 명령어는 operation을 가진 seal에 fact 서명을 추가하기 위해 사용됩니다. operation을 가진 seal 파일을 넘겨주어야 합니다.
멀티 시그나 멀티 노드를 사용할 경우 operation fact에 여러 개의 서명을 추가하는 것이 목적입니다.
$ ./mitum seal sign-fact --network-id=NETWORK-ID-FLAG <privatekey>
EXAMPLE
다음은 멀티 시그 계정으로부터 토큰을 전송하는 transfer operation을 담은 seal의 예제입니다. operation은 두 개의 fact_sign을 가져야 하지만 현재는 하나밖에 없습니다.
{
    "_hint": "seal-v0.0.1",
    "hash": "CgFaHkJEP966xRQjzPtXBUwzqgQYWB53RHwjBqyvmKHs",
    "body_hash": "Akjx1kJZKzyYMo2eVbqcUvtEfivDEGsK4yeUUuNwbGmu",
    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
    "signature": "381yXZ8qZBYQXDBaGr1KyAcsMJyB9HZLo1aQQRsxhx854aMYm5n7nh3NXzsJHpEhiYHgWUYnCtbAZaVsQ8pe6nEnLaHCXizY",
    "signed_at": "2021-06-10T09:54:35.868873Z",
    "operations": [
        {
            "hash": "Eep8SJH7Vkqft3BcvKYd9NY14Zgzmhyp7Uts2GmpaS5N",
            "fact": {
                "_hint": "mitum-currency-transfers-operation-fact-v0.0.1",
                "hash": "Eu1b4gr528Xy4u2sg97DsEo5uj9BuQEMjHzJxdsLgH48",
                "token": "MjAyMS0wNi0xMFQwOTo1NDozNS44NjQwOTha",
                "sender": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
                "items": [
                    {
                        "_hint": "mitum-currency-transfers-item-single-amount-v0.0.1",
                        "receiver": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
                        "amounts": [
                            {
                            "_hint": "mitum-currency-amount-v0.0.1",
                            "amount": "100",
                            "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
                    "signature": "AN1rKvtZFkx5e4NexvBSjjJkuzUj45UKau8DL2JZx5d1htnbnkmPmHnNbgwqfvUnz8KHpUR72Z9YxD4JVQhdh4JCzGv9zMDDG",
                    "signed_at": "2021-06-10T09:54:35.868223Z"
                }
            ],
            "memo": "",
            "_hint": "mitum-currency-transfers-operation-v0.0.1"
        }
    ]
}
fact_sign 추가 후 위 json은 다음과 같아집니다.
$ SIGNER1_PUB_KEY=2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu
$ SIGNER2_PUB_KEY=sdjgo1jJ2kxAxMyBj6qZDb8okZpwzHYE8ZACgePYW4eTmpu
$ SIGNER2_PRV_KEY=L5AAoEqwnHCp7WfkPcUmtUX61ppZQww345rEDCwB33jVPud4hzKJmpr
$ NETWORK_ID=mitum
$ ./mitum seal sign-fact $SIGNER2_PRV_KEY --seal data.json --network-id=$NETWORK_ID --pretty

{
    "_hint": "seal-v0.0.1",
    "hash": "GiADUurx7qVwyeu8XUNQgmNpqmtN9UDzockhLNKXzYN6",
    "body_hash": "Ci7yzpahGtXqpWs3EGfoqnmUhTgbRhdkgb2GupsJRvgB",
    "signer": "sdjgo1jJ2kxAxMyBj6qZDb8okZpwzHYE8ZACgePYW4eTmpu",
    "signature": "381yXYnDDMYrZ4asLpAYgD7AHDAGMsVih11S3V2jCwNdvJJxeA96whPnth4DxXoJ3RiK8vBpvVKRvXJsPpDpZZ2GMagAmaBi",
    "signed_at": "2021-06-10T10:01:27.690429Z",
    "operations": [
        {
            "_hint": "mitum-currency-transfers-operation-v0.0.1",
            "hash": "AduowWC9mHTCeRp8aqN4dQxHjKGH8xdm8vqxcMj7SfUZ",
            "fact": {
                "_hint": "mitum-currency-transfers-operation-fact-v0.0.1",
                "hash": "Eu1b4gr528Xy4u2sg97DsEo5uj9BuQEMjHzJxdsLgH48",
                "token": "MjAyMS0wNi0xMFQwOTo1NDozNS44NjQwOTha",
                "sender": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
                "items": [
                    {
                        "_hint": "mitum-currency-transfers-item-single-amount-v0.0.1",
                        "receiver": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "100",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
                    "signature": "AN1rKvtZFkx5e4NexvBSjjJkuzUj45UKau8DL2JZx5d1htnbnkmPmHnNbgwqfvUnz8KHpUR72Z9YxD4JVQhdh4JCzGv9zMDDG",
                    "signed_at": "2021-06-10T09:54:35.868223Z"
                },
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "sdjgo1jJ2kxAxMyBj6qZDb8okZpwzHYE8ZACgePYW4eTmpu",
                    "signature": "381yXZ9yqzCSzUZZUuQvU3ZMHgM9Pa5MQUo2hKGhPFW4ZuMCC3eK2iGYvx3gwQD3LCfELuUXejAQiMmeKaNAEoZVPDf1gpkE",
                    "signed_at": "2021-06-10T10:01:27.690034Z"
                }
            ],
            "memo": ""
        }
    ]
}

Operation Generation

각 모델은 다음에서 각각 설명하는 operation을 생성할 수 있습니다.
operation 생성을 위해, Seal Command 를 사용해야 합니다.
$ ./mitum seal <operation name> ...

currency

이 모델은 다음 operation 생성 명령어를 지원합니다.

Operations for Currency

currency-register

Register new currency id

currency-policy-updater

Update currency policy

suffrage-infration

Increase amount of tokens

Operations for Account

create-account

Create new account

key-updater

Update account keys

transfer

Transfer amount of tokens

create-account
create-account 로 계정을 생성하세요.
$ ./mitum seal create-account --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency,amount> --key=KEY@... --threshold=THRESHOLD
  • KEY: <pub key, weight>

EXAMPLE
ac0ac1 두 계정을 생성하는 과정을 예제로 설명합니다.
키페어를 생성하는 방법은 key 을 참고하세요.
ac0 를 생성하는 operation은 다음과 같습니다.
  1. Create Single Sig Account

생성할 계정의 정보는 다음과 같습니다.
sender's account - who create new account
private key: L5GTSKkRs9NPsXwYgACZdodNUJqCAWjz2BccuR4cAgxJumEZWjokmpr
address: Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca

ac0
public key - weight: cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu - 100
threshold: 100
initial balance: 500 MCC
$ NETWORK_ID="mitum"

$ SENDER_PRV=L5GTSKkRs9NPsXwYgACZdodNUJqCAWjz2BccuR4cAgxJumEZWjokmpr

$ SENDER_ADDR=Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca

$ AC0_PUB=cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu

$ ./mitum seal create-account --network-id=$NETWORK_ID $SENDER_PRV $SENDER_ADDR MCC,500 --key=$AC0_PUB,100 --threshold=100 --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "Xr7HS7rnbfxTrNbr6qRJ64on6KFuMzvJf5Z6BGqVZsX",
    "body_hash": "EJ93htxhUh2edJhBujMCHhpvGGHQoBic8KQ7VzggxKw1",
    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
    "signature": "381yXZUffVp3gmKD2WJA6756SeDy16d3PF6Ym15HBL89rs1YhT1cW4zVnWD17mhBdhfhutu3848GPd9zTMDqUFmkE8rUWmCs",
    "signed_at": "2021-06-10T14:06:17.60152Z",
    "operations": [
        {
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "8ezjZDuC44U2ZFPDkebMyLEYNQBPUUnRjHyfSTeQs9gk",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "F1o51xXWnnQYUVV6JA44beJeKKxuJi3Tv8DzvREodHhA",
                "token": "MjAyMS0wNi0xMFQxNDowNjoxNy41OTczMDNa",
                "sender": "Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLu",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "500",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                    "signature": "381yXYyRo91cqu5gFp5GtHWCiYmsssbFxx95MaL8gH4koBCZ5AfnRqYEpWMxcxgKmeEWsRPVJ8zWytAMLiA9zQes9qGnbcj8",
                    "signed_at": "2021-06-10T14:06:17.601089Z"
                }
            ],
            "memo": ""
        }
    ]
}
위 json 메시지가 seal에 담겨 전송됩니다.
  1. Create Multi Sig Account

참고

  • Mitum Currency에서 한 계정에 의해 서명된 다수의 operation은 한 블록에서 처리될 수 없습니다.

  • 예를 들어 ac0 에서 각각 ac1, ac2 로 5 amount를 전송하는 두 별개의 operation은 한 번에 처리될 수 없습니다.

  • 이 경우 처음 도착한 operation만이 처리되며 나머지는 무시됩니다.

sender가 두 계정 ac0ac1 을 하나의 seal로 한 번에 생성하려 한다고 가정해보세요. 그러면 sender는 ac0ac1 각각에 대한 item을 생성하여 operation에 추가해야 합니다.
즉, sender는 두 게정을 생성하는 오직 하나의 operation을 생성하고 seal에 담아 전송해야 합니다. 이 seal은 성공적으로 처리될 것입니다. sender가 같은 여러 개의 operation을 생성할 필요가 없습니다.
sender's account - who create new account
private key: L5GTSKkRs9NPsXwYgACZdodNUJqCAWjz2BccuR4cAgxJumEZWjokmpr
address: Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca

ac0
public key - weight: cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu - 100
threshold: 100
initial balance: 50 MCC

ac1
public key - weight: sdjgo1jJ2kxAxMyBj6qZDb8okZpwzHYE8ZACgePYW4eTmpu - 100
threshold: 100
initial balance: 50 MCC
다음과 같은 명령어를 실행하세요.
$ NETWORK_ID=mitum

$ NODE=https://127.0.0.1:54321

$ SENDER_PRV=L5GTSKkRs9NPsXwYgACZdodNUJqCAWjz2BccuR4cAgxJumEZWjokmpr

$ SENDER_ADDR=Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca

$ CURRENCY_ID=MCC

$ AC0_PUB=cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu

$ AC1_PUB=sdjgo1jJ2kxAxMyBj6qZDb8okZpwzHYE8ZACgePYW4eTmpu

$ ./mitum seal create-account --network-id=$NETWORK_ID \
    $SENDER_PRV $SENDER_ADDR $CURRENCY_ID,50 \
        --key=$AC0_PUB,100 |
    ./mitum seal create-account --network-id=$NETWORK_ID \
        $SENDER_PRV $SENDER_ADDR $CURRENCY_ID,50 \
        --key=$AC1_PUB,100 --seal=- | \
    ./mitum seal send --network-id="$NETWORK_ID" \
        $SENDER_PRV --seal=- --node=$NODE --tls-insecure | jq -R '. as $line | try fromjson catch $line'
{
    "_hint": "seal-v0.0.1",
    "hash": "HV1tT3D639TiYe6bmamXtesvNjAN8tJ7AmgmeB6STrwz",
    "body_hash": "Gg5KQzzNPAt5PiLrcE5kjMbd4jB7Vk4ooBmN81yWDqYv",
    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
    "signature": "381yXZ1szjaYdxsznCpSvg19yS1tKUw1yPmgXBX6Ehf5ZcKNaMCRkJ8PaNS34rUwLSZ88EPh8vFq1FfRncHiTfo1v9adHCSH",
    "signed_at": "2021-06-10T15:01:13.080144Z",
    "operations": [
        {
            "memo": "",
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "AhqQMGZHDCeJDp74aQJ8rEXMC6GgQtpxP3rXnjjP41ui",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "3fDBD1i6V5VpGxB1di6JGgMPhyWZeWRML8FX4LnYXqJE",
                "token": "MjAyMS0wNi0xMFQxNTowMToxMy4wNDA0OTZa",
                "sender": "Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLu",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "50",
                                "currency": "MCC"
                            }
                        ]
                    },
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "EuCb6BVafkV1tBLsrMqkxojkanJCM4bvmG6JFUZ4s7XL",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "sdjgo1jJ2kxAxMyBj6qZDb8okZpwzHYE8ZACgePYW4eTmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "50",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                    "signature": "AN1rKvthtCymTu7gv2fSrMhGwqVuK3o24FrDe6GGLzRU8N5SWF62nPs3iKcEjuzwHya6P9JmrNLRF95ri8QTE4NBc66TxhCHm",
                    "signed_at": "2021-06-10T15:01:13.053303Z"
                }
            ]
        }
    ]
}
"2021-06-10T15:01:13.083634Z INF trying to send seal module=command-send-seal"
"2021-06-10T15:01:13.171266Z INF sent seal module=command-send-seal"
transfer
transfer 명령어를 사용해 계정 사이에 토큰을 전송하세요.
$ ./mitum seal transfer --network-id=NETWORK-ID-FLAG <privatekey> <sender> <receiver> <currency,amount> ...
EXAMPLE
다음은 10 MCC token을 ac0 에서 ac1 로 전송하는 예제입니다.
$ AC0_PRV=KzUYFHNzxvUnZfm1ePJJ4gnLcLtMv1Tvod7Fib2sRuFmGwzm1GVbmpr

$ AC0_ADDR=FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca

$ AC1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ CURRENCY_ID=MCC

$ NETWORK_ID="mitum"

$ ./mitum seal transfer --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $AC1_ADDR $CURRENCY_ID,10 --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "EJDzHbusvvcknN9NWaK1wjuvSTav2TVfnDmtRnqVjEVn",
    "body_hash": "FWLTyQePguo6CFxH8SgEHesoLL8ab3FofEw9nXHDDLMp",
    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
    "signature": "381yXZMbRqwMgfWwJNk4rWNuaJenJMHZU3HBufz7Uo4Yj3zo944oeJeGoKjUDyCJXuL4pZLt49gqW2FHV3YuB5zBR24h96ZH",
    "signed_at": "2021-06-14T03:42:11.969679Z",
    "operations": [
        {
            "_hint": "mitum-currency-transfers-operation-v0.0.1",
            "hash": "F3WZYRgcwwYENiVXx6J6zKPqkiDjSZcuF2vUUPiyR3n9",
            "fact": {
                "_hint": "mitum-currency-transfers-operation-fact-v0.0.1",
                "hash": "7xzioXfnkKU1qrFvgeWK1KrhR71RMHMSBZdpWRVK3MUD",
                "token": "MjAyMS0wNi0xNFQwMzo0MjoxMS45NjUyNjNa",
                "sender": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
                "items": [
                    {
                        "_hint": "mitum-currency-transfers-item-single-amount-v0.0.1",
                        "receiver": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "10",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
                    "signature": "AN1rKvtRQeMWcFQ9oPLqgakgW33fed4mCcxxfQwi3icWLyn19AKJ3XpYehA8njvAi7qzgGSVpv23JXBDcXbwiZvQkHBj6T8jw",
                    "signed_at": "2021-06-14T03:42:11.96891Z"
                }
            ],
            "memo": ""
        }
    ]
}
operation을 네트워크로 바로 전송하고 싶다면,
key-updater
key-updater 로 계정 keys를 업데이트하세요.
새로운 공개키로 계정 keys를 업데이트하여도 주소는 변경되지 않습니다.
$ ./mitum seal key-updater --network-id=NETWORK-ID-FLAG <privatekey> <target> <currency> --key=KEY@... --threshold=THRESHOLD
  • KEY: <pub key, weight>

계정 keys에 대한 더 자세한 정보는 Multi Sig Account 를 참고하세요.
EXAMPLE
다음은 key-updater 의 예제입니다. 예제에서는 ac0 의 keys를 교체하려고 하고 있습니다.
ac0 - target account
private key: KzUYFHNzxvUnZfm1ePJJ4gnLcLtMv1Tvod7Fib2sRuFmGwzm1GVbmpr
public key: 2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu
address: FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca

ac1 - new key
public key: 247KCJyus9NYJii9rkT4R3z6GxengcwYQHwRKA6DySbiUmpu
$ NETWORK_ID="mitum"

$ NODE=https://127.0.0.1:54321

$ AC0_PRV=KzUYFHNzxvUnZfm1ePJJ4gnLcLtMv1Tvod7Fib2sRuFmGwzm1GVbmpr

$ AC0_PUB=2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu

$ AC0_ADDR=FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca

$ AC1_PUB=247KCJyus9NYJii9rkT4R3z6GxengcwYQHwRKA6DySbiUmpu

$ CURRENCY_ID=MCC

$ ./mitum seal key-updater --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR --key $AC1_PUB,100 $CURRENCY_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "GvuGxKCTKWqXzgzxk3iWVGkSPAMn1nBNbAu7qgzHB8y6",
    "body_hash": "8gyB4eE7yQvneA463ZnM8LEWKDCthm8mKEFcfvAmk2pg",
    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
    "signature": "381yXZWCaZy3G5VLse9NCBMmJg8bPWoY4rmyAWMTRVjLKZP9WkexgJfN8EP4G2P64MPchFKtsYZ2QsNyu31rrjKQN4THtEtz",
    "signed_at": "2021-06-14T03:45:21.821896Z",
    "operations": [
        {
            "_hint": "mitum-currency-keyupdater-operation-v0.0.1",
            "hash": "4fFKpjDBmSrka3C3Q62fz5JYGZstZmkQTe27vgyNj4A9",
            "fact": {
                "_hint": "mitum-currency-keyupdater-operation-fact-v0.0.1",
                "hash": "5yaMz2aSKS5H1wtd4YVcU4q5awbaxu7bhhswX3ss8XCb",
                "token": "MjAyMS0wNi0xNFQwMzo0NToyMS44MTczNjNa",
                "target": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
                "keys": {
                    "_hint": "mitum-currency-keys-v0.0.1",
                    "hash": "GmUiuEbsoTVLSirRWMZ2WcxT69enhEXNfskAnRJby8he",
                    "keys": [
                        {
                            "_hint": "mitum-currency-key-v0.0.1",
                            "weight": 100,
                            "key": "247KCJyus9NYJii9rkT4R3z6GxengcwYQHwRKA6DySbiUmpu"
                        }
                    ],
                    "threshold": 100
                },
                "currency": "MCC"
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
                    "signature": "AN1rKvtPv6CuiW36Q4g1wtmsGNy2Fc3ierpHgfnjXjdqjDE3wvSH293FVDYy9Yf9VTNadfMGJ38WC39hthZuGkau3vBGq7ijP",
                    "signed_at": "2021-06-14T03:45:21.821399Z"
                }
            ],
            "memo": ""
        }
    ]
}
operation을 바로 전송하고 싶다면,
$ ./mitum seal key-updater --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR \
    --key $AC1_PUB,100" $CURRENCY_ID \
    | ./mitum seal send --network-id=$NETWORK_ID \
    $AC0_PRV --seal=- --node=$NODE --tls-insecure
또한, 계정 keys가 정말로 바뀌었는지 확인할 수 있습니다.
$ find blockfs -name "*-states-*" -print | sort -g | xargs -n 1 gzcat |  grep '^{' | jq '. | select(.key == "'$AC0_ACC_KEY'") | [ "height: "+(.height|tostring),   "state_key: " + .key, "key.publickey: " + .value.value.keys.keys[0].key, "key.weight: " + (.value.value.keys.keys[0].weight|tostring), "threshold: " + (.value.value.keys.threshold|tostring)]'
[
    "height: 3",
    "state_key: GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623-mca:account",
    "key.publickey: 2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
    "key.weight: 100",
    "threshold: 100"
]
[
    "height: 104",
    "state_key: GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623-mca:account",
    "key.publickey: 247KCJyus9NYJii9rkT4R3z6GxengcwYQHwRKA6DySbiUmpu",
    "key.weight: 100",
    "threshold: 100"
]
currency-register
currency-register 를 사용해 새로운 currency 토큰을 등록하세요.
$ ./mitum seal currency-register --network-id=NETWORK-ID-FLAG --feeer=STRING <privatekey> <currency-id> <genesis-amount> <genesis-account>
새로운 currency 등록 시, 설정해야할 요소는 다음과 같습니다.
  • genesis account: 새로운 currency 등록과 함께 발행될 토큰이 입금될 계정

  • genesis amount: 새롭게 발행될 토큰의 양

  • –policy-new-account-min-balance=<amount> 을 설정해야 합니다.

  • feeer: feeer는 세 정책 중 선택될 수 있습니다; {nil, fixed, ratio}.

    • nil - 수수료를 지급하지 않습니다.

    • fixed - 고정 수수료를 지급합니다.

    • ratio - operation amount의 일정 비율로 책정한 수수료를 지급합니다.

    • 수수료 정책이 fixed인 경우, –feeer-fixed-receiver=<fee receiver account address>, –feeer-fixed-amount=<fee amount> 를 설정합니다.

    • 수수료 정책이 ratio인 경우, –feeer-ratio-receiver=<fee receiver account address>, –feeer-ratio-ratio=<fee ratio, multifly by operation amount>, –feeer-ratio-min=<minimum fee>, –feeer-ratio-max=<maximum fee> 을 설정합니다.

새로운 currency를 등록할 때, 합의에 참여하는 노드들의 서명이 threshold(67%)를 넘겨야 operation이 처리됩니다.
EXAMPLE
새로운 currency MCC2를 다음과 같은 조건에 따라 등록한다고 가정해봅시다.
genesis-account : ac1
genesis-amount : 9999999999999
currency-id : MCC2
feeer : fixed
feeer-fixed-receiver : ac1
feeer-fixed-amount : 3
seal sender : ac1
suffrage node : n0, n1, n2, n3
다음과 같은 명령어를 통해 등록합니다.
$ NETWORK_ID="mitum"

$ AC1_ADDR="HWXPq5mBSneSsQis6BbrNT6nvpkafuBqE6F2vgaTYfAC-a000:0.0.1"

$ AC1_PRV="792c971c801a8e45745938946a85b1089e61c1cdc310cf61370568bf260a29be-0114:0.0.1"

$ N0_PRV=<n0 private key>

$ N1_PRV=<n1 private key>

$ N2_PRV=<n2 private key>

$ N3_PRV=<n3 private key>

$ ./mitum seal currency-register --network-id=$NETWORK_ID --feeer=fixed --feeer-fixed-receiver=$AC1_ADDR \
    --feeer-fixed-amount=3 --policy-new-account-min-balance=10 $N0_PRV MCC2 9999999999999 $AC1_ADDR \
    | ./mitum seal sign-fact $N1_PRV --network-id="$NETWORK_ID" --seal=- \
    | ./mitum seal sign-fact $N2_PRV --network-id="$NETWORK_ID" --seal=- \
    | ./mitum seal sign-fact $N3_PRV --network-id="$NETWORK_ID" --seal=- \
    | ./mitum seal send --network-id="$NETWORK_ID" $AC1_PRV --seal=-
각 currency는 예금만 가능한 zero account를 가지고 있습니다. zero account는 token을 태우는데 사용됩니다. zero account는 공개키가 등록되어있지 않기 때문에 예금만 가능합니다.
zero account의 주소는 모두 <currency id>-Xmca 형식을 가지고 있습니다. 예를 들어, PEN의 zero account의 주소는 PEN-Xmca 입니다.
$ curl --insecure http://localhost:54320/account/PEN-Xmca | jq
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-account-value-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-account-value-v0.0.1",
        "hash": "EJvkxncxfVQNncdKZtjQTH2XuT5ECRiqSZA7LLE14zqi",
        "address": "PEN-Xmca",
        "keys": {
            "_hint": "mitum-currency-keys-v0.0.1",
            "hash": "",
            "keys": [],
            "threshold": 0
        },
        "balance": [
            {
                "_hint": "mitum-currency-amount-v0.0.1",
                "amount": "100000000000000000000000000",
                "currency": "PEN"
            }
        ],
        "height": 41,
        "previous_height": 0
    },
    "_links": {
        "block": {
            "href": "/block/41"
        },
        "previous_block": {
            "href": "/block/0"
        },
        "self": {
            "href": "/account/PEN-Xmca"
        },
        "operations": {
            "href": "/account/PEN-Xmca/operations"
        },
        "operations:{offset}": {
            "href": "/account/PEN-Xmca/operations?offset={offset}",
            "templated": true
        },
        "operations:{offset,reverse}": {
            "templated": true,
            "href": "/account/PEN-Xmca/operations?offset={offset}&reverse=1"
        }
    }
}
currency-policy-updater
currency-policy-updater 명령어를 사용하여, currency와 관련된 정책을 업데이트하세요.
$ ./mitum seal currency-policy-updater --network-id=NETWORK-ID-FLAG --feeer=STRING <privatekey> <currency-id>
우선 API를 통해 등록된 currency의 정보를 확인하세요.
정책 업데이트 시, 합의에 참여하는 노드들의 서명이 threshold(67%)를 넘겨야 operation이 처리됩니다.
$ curl --insecure -v https://localhost:54320/currency/MCC2 | jq
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-currency-design-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-currency-design-v0.0.1",
        "amount": {
            "_hint": "mitum-currency-amount-v0.0.1",
            "amount": "9999999999999",
            "currency": "MCC2"
        },
        "genesis_account": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
        "policy": {
            "_hint": "mitum-currency-currency-policy-v0.0.1",
            "new_account_min_balance": "10",
            "feeer": {
                "_hint": "mitum-currency-fixed-feeer-v0.0.1",
                "type": "fixed",
                "receiver": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
                "amount": "3"
            }
        }
    },
    "_links": {
        "self": {
            "href": "/currency/MCC2"
        },
        "currency:{currencyid}": {
            "templated": true,
            "href": "/currency/{currencyid:.*}"
        },
        "block": {
            "href": "/block/10"
        },
        "operations": {
            "href": "/block/operation/goNANpmA1BcnXA6TVL6AKkoxsmiaT2F5ss5zoSh7Wdt"
        }
    }
}
currency-policy-updater 통해 업데이트할 수 있는 정책은 fee-related policy와 계정 생성 시의 minimum balance value입니다.
EXAMPLE
다음 조건에 따라 MCC2의 정책을 업데이트한다고 가정해봅시다.
currency-id : MCC2

Policy to be updated
- feeer : ratio
- feeer-ratio-receiver : ac1
- feeer-ratio-ratio : 0.5
- feeer-ratio-min : 3
- feeer-ratio-max : 1000
- policy-new-account-min-balance : 100

suffrage node : n0, n1, n2, n3
명령어를 실행하면,
$ NETWORK_ID="mitum"

$ AC1_ADDR="HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca"

$ AC0_PRV="KzUYFHNzxvUnZfm1ePJJ4gnLcLtMv1Tvod7Fib2sRuFmGwzm1GVbmpr"

$ N0_PRV=<n0 private key>

$ N1_PRV=<n1 private key>

$ N2_PRV=<n2 private key>

$ N3_PRV=<n3 private key>

$ ./mitum seal currency-policy-updater --network-id=$NETWORK_ID --feeer="ratio" --feeer-ratio-receiver=$AC1_ADDR \
    --feeer-ratio-ratio=0.5 --feeer-ratio-min=3 --feeer-ratio-max=1000 --policy-new-account-min-balance=100 $N0_PRV MCC2 \
    | ./mitum seal sign-fact $N1_PRV --network-id=$NETWORK_ID --seal=- \
    | ./mitum seal sign-fact $N2_PRV --network-id=$NETWORK_ID --seal=- \
    | ./mitum seal sign-fact $N3_PRV --network-id=$NETWORK_ID --seal=- \
    | ./mitum seal send --network-id=$NETWORK_ID $AC0_PRV --seal=-
결과를 확인하면,
$ curl --insecure https://localhost:54320/currency/MCC2 | jq
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-currency-design-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-currency-design-v0.0.1",
        "amount": {
            "_hint": "mitum-currency-amount-v0.0.1",
            "amount": "9999999999999",
            "currency": "MCC2"
        },
        "genesis_account": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
        "policy": {
            "_hint": "mitum-currency-currency-policy-v0.0.1",
            "new_account_min_balance": "100",
            "feeer": {
                "_hint": "mitum-currency-ratio-feeer-v0.0.1",
                "type": "ratio",
                "receiver": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                "ratio": 0.5,
                "min": "3",
                "max": "1000"
            }
        }
    },
    "_links": {
        "currency:{currencyid}": {
            "href": "/currency/{currencyid:.*}",
            "templated": true
        },
        "block": {
            "href": "/block/13"
        },
        "operations": {
            "href": "/block/operation/3HxC5VP5Fjzent7uVVLsK44i1tp8ooH4f2Vh4c4uWM4e"
        },
        "self": {
            "href": "/currency/MCC2"
        }
    }
}
suffrage-inflation
suffrage-inflation 를 사용해 존재하는 currency 토큰에 인플레이션을 발생시킵니다.
$ ./mitum seal suffrage-inflation --network-id=NETWORK-ID-FLAG <privatekey> <inflation item> ...
  • inflation item: <receiver-account>,<currency-id>,<inflation-amount>

Mitum Currency에 currency를 등록하기 위한 두 가지 방법이 있습니다.
  • 초기 genesis currency 생성을 통해

  • 네트워크가 살아있을 때 새로운 currency를 등록함으로써

등록된 currency에는 총 공급량이 있습니다. Mitum Currency는 기존 총 공급량에 일정량의 토큰을 추가할 수 있습니다.
새로운 currency를 생성할 때, 설정해야 할 요소에는 다음과 같은 것들이 있습니다.
  • 추가로 발행되는 토큰을 입금할 receiver-account.

currency에 인플레이션을 일으킬 때, 합의에 참여하는 노드들의 서명이 threshold(67%)를 넘겨야 operation이 처리됩니다.
EXAMPLE
우리는 다음 조건에 따라 MCC에 인플레이션을 일으키고자 합니다.
operation-sender-account : ac1
receiver-account : ac2
inflation-amount : 9999999999999
currency-id : MCC
seal sender : ac1
suffrage node : n0, n1, n2, n3
이를 실행하면,
$ NETWORK_ID="mitum"

$ AC1_PRV="L2Q4PqxrhgS39jgGoXsV92LaCHRF2SqTLRwMhCC6Q6in9Vb19aDLmpr"

$ AC2_ADDR="HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca"

$ N0_PRV=<n0 private key>

$ N1_PRV=<n1 private key>

$ N2_PRV=<n2 private key>

$ N3_PRV=<n3 private key>

$ ./mitum seal suffrage-inflation --network-id=$NETWORK_ID $N0_PRV MCC 9999999999999 $AC2_ADDR \
    | ./mitum seal sign-fact $N1_PRV --network-id=$NETWORK_ID --seal=- \
    | ./mitum seal sign-fact $N2_PRV --network-id=$NETWORK_ID --seal=- \
    | ./mitum seal sign-fact $N3_PRV --network-id=$NETWORK_ID --seal=- \
    | ./mitum seal send --network-id=$NETWORK_ID $AC1_PRV --seal=-

currency-extension

이 모델은 다음 operation 생성 명령어를 지원합니다.

Operations for Contract Account

create-contract-account

Create new contract account

withdraw

Withdraw tokens from contract account

create-contract-account
create-contract-account 명령어로 새로운 컨트랙트 계정을 생성하는 operation을 작성할 수 있습니다.
$ ./mitum seal create-contract-account --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency,amount> --key=KEY@... --threshold=THRESHOLD
  • KEY: <pub key, weight>

컨트랙트 계정 주소 생성 방법은 일반적인 create-account 와 동일합니다.
하지만 컨트랙트 계정은 대응되는 공개키를 가지고 있지 않기 때문에 operation의 전송자(sender)가 될 수 없습니다.

EXAMPLE

다음은 새로운 컨트랙트 계정을 생성하는 operation을 작성하는 과정의 예시입니다.
$ NETWORK_ID=mitum

$ NODE=https://127.0.0.1:54321

$ SENDER_PRV=L5GTSKkRs9NPsXwYgACZdodNUJqCAWjz2BccuR4cAgxJumEZWjokmpr

$ SENDER_ADDR=Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca

$ CURRENCY_ID=MCC

$ CA_PUB=cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu

$ ./mitum seal create-contract-account --network-id=$NETWORK_ID $SENDER_PRV $SENDER_ADDR $CURRENCY_ID,50 --key=$CA_PUB,100 --threshold=100 --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "FesvoWab1rxiqThwa3NcatCYQjmsAHVdW3jhjgAvNUeH",
    "body_hash": "7VP1MkTMShuMkTFaVZ5NQfSc4znE8fBdBDJqNVpz9AQY",
    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
    "signature": "381yXZ35xwEQHrx29K9gxEByxCEfNjq4kk2RAc9R1pHxFvsb3ipBj6YATbcibNGmt9Qmjfk37Pj1dXEhUpxgpsAiomhiLdev",
    "signed_at": "2022-09-22T05:10:53.613948Z",
    "operations": [
        {
            "_hint": "mitum-currency-create-contract-accounts-operation-v0.0.1",
            "hash": "9CGe19v8J2vgtDzYYwrYDmdvSXuoDitRMW5yCLmt1wHS",
            "fact": {
                "_hint": "mitum-currency-create-contract-accounts-operation-fact-v0.0.1",
                "hash": "3TdxxmTqL8azYWT7jXJ964YsSVhd4D3fZbfK1a5Mcait",
                "token": "MjAyMi0wOS0yMlQwNToxMDo1My42MTM4Wg==",
                "sender": "Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-contract-accounts-multiple-amounts-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLu",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "50",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                    "signature": "AN1rKvtLiUW7aMuUjm2VAgfprbHBZebQyhpJYHbSGG3wXVKe3w73LZQ59DE8tRVQkepDqiENZbU8GQyHQ7Jb9U8n7A3v9BZv6",
                    "signed_at": "2022-09-22T05:10:53.613936Z"
                }
            ],
            "memo": ""
        }
    ]
}
withdraw
withdraw 명령어로 컨트랙트 계정으로부터 토큰을 인출할 수 있습니다.
$ ./mitum seal withdraw --network-id=NETWORK-ID-FLAG <privatekey> <sender> <target> <currency-amount> ...
EXAMPLE
다음은 ca0 으로부터 10 MCC 를 인출하는 예시입니다.
$ AC0_PRV=KzUYFHNzxvUnZfm1ePJJ4gnLcLtMv1Tvod7Fib2sRuFmGwzm1GVbmpr

$ AC0_ADDR=FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca

$ CA1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ CURRENCY_ID=MCC

$ NETWORK_ID="mitum"

$ ./mitum seal withdraw --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CA1_ADDR $CURRENCY_ID,10 --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "3Cqw2bKvqRRscAT6DqACM9B4qtQPKi3nkSWV9emssvLH",
    "body_hash": "8onqhQvFNYTvAu5XeYpSx6GD1o6ybAoUsDR7bBs1M7NH",
    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
    "signature": "381yXZ4NQCLLjLbkc8oN3ZuDUt5Vix9QToVKRB5dyKsiWMyVZXA2EgvkX6fpsURdfuxLddj8yMD1JQWLLnB8xjjVHxr4FgqD",
    "signed_at": "2022-09-22T05:21:21.784792Z",
    "operations": [
        {
            "hash": "5GUZ7nCx1V1Dc4MW28cX3N59wqjjJ9DFWZ3aPUKHDuSe",
            "fact": {
                "_hint": "mitum-currency-contract-account-withdraw-operation-fact-v0.0.1",
                "hash": "J3mNeqrZwSSQZGorvXxDaAC2L88uF3akWDNnvQZzgCNP",
                "token": "MjAyMi0wOS0yMlQwNToyMToyMS43ODQ1OTha",
                "sender": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
                "items": [
                    {
                        "_hint": "mitum-currency-withdraws-item-multi-amounts-v0.0.1",
                        "target": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "10",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu",
                    "signature": "381yXZHAgjXqDFJ38277rQFt8MamuhQCRdbqMuVah1TNYFEVg2cLihXCJBrGeUNzUiPpsGwAeHh2zaJG3mtKdc9VmJVU3dbF",
                    "signed_at": "2022-09-22T05:21:21.78478Z"
                }
            ],
            "memo": "",
            "_hint": "mitum-currency-contract-account-withdraw-operation-v0.0.1"
        }
    ]
}

document

이 모델은 다음 operation 생성 명령어를 지원합니다.

Operations for Document

create-document

Create new document

update-document

Update the registered document

sign-document

Sign the registered document

실제로 CLI를 통해 문서를 생성하기 위해서는 create-document 가 아닌 문서 형태에 맞는 명령어를 사용해야 합니다.
문서 형태는 blockcityblocksign 로 나누어 집니다. 각 명령어는 다음과 같습니다.
blockcity:
  • document create-blockcity-user-document

  • document create-blockcity-land-document

  • document create-blockcity-voting-document

  • document create-blockcity-history-document

  • document update-blockcity-user-document

  • document update-blockcity-land-document

  • document update-blockcity-voting-document

  • document update-blockcity-history-document

blocksign:
  • document create-blocksign-document

  • sign-document

또한, 각 문서 형태 별 문서 ID 접미사가 존재합니다.
blockcity:
  • user doc: cui

  • land doc: cli

  • voting doc: cvi

  • history doc: chi

blocksign:
  • blocksign doc: sdi

create-document
create-document 명령어는 블록체인 상에 문서를 생성하기 위한 명령어입니다.
각 문서 형태에 맞는 적절한 명령어(document-type-command)는 다음과 같습니다.
  • create-blockcity-user-document

  • create-blockcity-land-document

  • create-blockcity-voting-document

  • create-blockcity-history-document

  • create-blocksign-document

$ ./mitum seal document <document-type-command> --network-id=NETWORK-ID-FLAG <privatekey> <sender> ...
EXAMPLE
예를 들어, 블록사인 문서를 생성하는 과정은 다음과 같습니다.
ac0 - sender account
private key:KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr
address:BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca
sign_code: signcode0

target document
title: example_doc
file hash: 8y8eHdmPsxZZGPFrKaYaHCQnDvcVmCAgB1XsNm7KGSxF
size: 1245
document id: exampledocsdi
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ CURRENCY_ID=MCC

$ NETWORK_ID="mitum"

$ FILE_HASH=8y8eHdmPsxZZGPFrKaYaHCQnDvcVmCAgB1XsNm7KGSxF

$ SIGN_CODE=signcode0

$ TITLE=example_doc

$ SIZE=1245

$ DOCUMENT_ID=exampledocsdi

$ ./mitum seal document create-blocksign-document --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $FILE_HASH $SIGN_CODE $DOCUMENT_ID $TITLE $SIZE $CURRENCY_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "GF4e4c8Xxvhb5YFwEzXoZi4nV3XjkyPf4dQpu8VAbeEH",
    "body_hash": "43nopiEfz3Rjad1j9jvAjf36kbqw4Nwj6QKBL5vkymhD",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "AN1rKvtaa6uDhZLd6okWV7PcEyDNoeVGDewMxfXSoBPiVj5pjkhT1nr3C5RWtF9B8YpGijSaZgKDR2HvozuLVAQhhn4h6dfmK",
    "signed_at": "2022-09-27T07:50:31.80218Z",
    "operations": [
        {
            "fact": {
                "_hint": "mitum-create-documents-operation-fact-v0.0.1",
                "hash": "69n9wHdnhowxPUu3ufZLPfZecnssDeky8wTykWq3M2Xj",
                "token": "MjAyMi0wOS0yN1QwNzo1MDozMS44MDE5MTha",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "items": [
                    {
                        "_hint": "mitum-create-documents-item-v0.0.1",
                        "doc": {
                            "_hint": "mitum-blocksign-document-data-v0.0.1",
                            "info": {
                                "_hint": "mitum-document-info-v0.0.1",
                                "docid": {
                                    "_hint": "mitum-document-id-v0.0.1",
                                    "id": "exampledocsdi"
                                },
                                "doctype": "mitum-blocksign-document-data"
                            },
                            "owner": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                            "filehash": "8y8eHdmPsxZZGPFrKaYaHCQnDvcVmCAgB1XsNm7KGSxF",
                            "creator": {
                                "_hint": "mitum-blocksign-docsign-v0.0.1",
                                "address": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                                "signcode": "signcode0",
                                "signed": true
                            },
                            "title": "example_doc",
                            "size": "1245",
                            "signers": null
                        },
                        "currency": "MCC"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZVwDoasGFrT2TgcqrZ2JmzW31BZWpeAPaeePHdREhavsbuSoVYHM1va5etWXXeMeBwLp94WJ17iYtM2JjjkUkfnzq8e",
                    "signed_at": "2022-09-27T07:50:31.80216Z"
                }
            ],
            "memo": "",
            "_hint": "mitum-create-documents-operation-v0.0.1",
            "hash": "AhwPxKWk9oRym6YwKQGRRqnxZQpSTY8i2RqZRZgPRTyM"
        }
    ]
}
update-document
update-document 명령어는 등록된 문서를 업데이트하기 위한 명령어입니다.
각 문서 형태에 맞는 명령어는 다음과 같습니다.
  • update-blockcity-user-document

  • update-blockcity-land-document

  • update-blockcity-voting-document

  • update-blockcity-history-document

이때 블록사인 문서는 업데이트할 수 없습니다.
$ ./mitum seal document <document-type-command> --network-id=NETWORK-ID-FLAG <privatekey> <sender> ...
EXAMPLE
예를 들어, blockcity-user 문서를 업데이트하기 위한 operation을 생성하는 과정은 다음과 같습니다.
ac0 - sender account
private key:KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr
address:BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

target document
document id: user0cui
gold/bankgold: 10, 10
hp/strength/agility/dexterity/charisma/intelligence/vital: 1, 1, 1, 1, 1, 1, 1
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ CURRENCY_ID=MCC

$ NETWORK_ID="mitum"

$ DOCUMENT_ID=user0cui

$ ./mitum seal document update-blockcity-user-document --network-id=mitum $AC0_PRV $AC0_ADDR 10 10 1 1 1 1 1 1 1 $DOCUMENT_ID $CURRENCY_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "5sddZRj6t3PZkgzz7LE3DzxtJmJwEp2BWiLiLQiZ9jHt",
    "body_hash": "4RMhiUA7d2izpkiJFp3VWF8bpQnNVwgrgGWYGgaHvHCu",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "AN1rKvtnLuJ82DMvBs8D7RQPfLPJDNhHjxdgDozs6B7eWmeQpAm1t4EESx2RZPV9RQ4m7zaPMunG9L3dQWigWCMHquPZuECFC",
    "signed_at": "2022-09-27T08:17:52.012673Z",
    "operations": [
        {
            "memo": "",
            "_hint": "mitum-update-documents-operation-v0.0.1",
            "hash": "6DDHb7aTMbYMr4zmorLcuBaucgppQ5tgw34RqjjWJju8",
            "fact": {
                "_hint": "mitum-update-documents-operation-fact-v0.0.1",
                "hash": "Gf1uoLeSCg3n176iPvhqsmXF61PMqar4D7DK3ko2iZjY",
                "token": "MjAyMi0wOS0yN1QwODoxNzo1Mi4wMTI0MTla",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "items": [
                    {
                        "_hint": "mitum-update-documents-item-v0.0.1",
                        "doc": {
                            "_hint": "mitum-blockcity-document-user-data-v0.0.1",
                            "info": {
                                "_hint": "mitum-document-info-v0.0.1",
                                "docid": {
                                    "_hint": "mitum-blockcity-user-document-id-v0.0.1",
                                    "id": "user0cui"
                                },
                                "doctype": "mitum-blockcity-document-user-data"
                            },
                            "owner": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                            "gold": 10,
                            "bankgold": 10,
                            "statistics": {
                                "_hint": "mitum-blockcity-user-statistics-v0.0.1",
                                "hp": 1,
                                "strength": 1,
                                "agility": 1,
                                "dexterity": 1,
                                "charisma": 1,
                                "intelligence": 1,
                                "vital": 1
                            }
                        },
                        "currency": "MCC"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZLrGDmhoL5htvF2qwjX4TXssgms5opqmXAgC2BybG47DG5Y2ZW5r57S1WT6qh2dXx6PY6d2DFZxhfnAWCpD1d79Btvz",
                    "signed_at": "2022-09-27T08:17:52.012653Z"
                }
            ]
        }
    ]
}
sign-document
sign-document 명령어는 문서에 서명하기 위한 operation을 생성해 줍니다.
이때, 블록시티 문서에는 서명할 수 없습니다.
$ ./mitum seal sign-document --network-id=NETWORK-ID-FLAG <privatekey> <sender> <documentid> <owner> <currency>
EXAMPLE
예를 들어, 블록사인 문서에 서명하는 operation을 생성하는 과정은 다음과 같습니다.
ac0 - signer account
private key:KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr
address:BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

ac1 - owner account
address: J1MbU4AaYnkGtvTJ2i8VpoPBY2rqP8GXqetQ41T8ZQKamca
$ NETWORK_ID="mitum"

$ AC0_PRV=KzUYFHNzxvUnZfm1ePJJ4gnLcLtMv1Tvod7Fib2sRuFmGwzm1GVbmpr

$ AC0_ADDR=FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca

$ AC1_ADDR=J1MbU4AaYnkGtvTJ2i8VpoPBY2rqP8GXqetQ41T8ZQKamca

$ CURRENCY_ID=MCC

$ DOCUMENT_ID=exampledocsdi

$ ./mitum seal sign-document --network-id=mitum $AC0_PRV $AC0_ADDR $DOCUMENT_ID $AC1_ADDR $CURRENCY_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "3FuuEGb7C8SmYEQC2Ykv3DmNc91CC1JHacTzt5dv6fCK",
    "body_hash": "DWh3hCPjz3BKxLAAARRvLDKHrFpGsbrhayNyf5pkfoEk",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "381yXZ1bHmxG5xEzaLNtqbTo35zYamL5B3GyhbmKJiShEej4v56dW1D16meJAzSZxqmwoiY8YmHsxj6yYbT9ddsUmJEf5Sa1",
    "signed_at": "2022-09-27T08:32:18.78323Z",
    "operations": [
        {
            "hash": "12nBfHCUVvvsKn7AZjL6DuSub8fzppTWshtcEWhvoBeC",
            "fact": {
                "_hint": "mitum-blocksign-sign-documents-operation-fact-v0.0.1",
                "hash": "A7rP6Rxp4LqRpirYP5T6zcGNxePUp7gJ9C37JQzL7tte",
                "token": "MjAyMi0wOS0yN1QwODozMjoxOC43ODI5ODNa",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "items": [
                    {
                        "_hint": "mitum-blocksign-sign-item-single-document-v0.0.1",
                        "documentid": "exampledocsdi",
                        "owner": "J1MbU4AaYnkGtvTJ2i8VpoPBY2rqP8GXqetQ41T8ZQKamca",
                        "currency": "MCC"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZAiPWdPHkEK6yHUKoiLCENiZQn7i2uUEFJFc6G2sPJfxrVYw6Tps9sU6TFEKKx948VyrNACtYM8decamVjE4Y6ZuZU8",
                    "signed_at": "2022-09-27T08:32:18.783211Z"
                }
            ],
            "memo": "",
            "_hint": "mitum-blocksign-sign-documents-operation-v0.0.1"
        }
    ]
}

feefi

이 모델은 다음과 같은 operation 생성을 지원합니다.

Operations for Feefi Pool

pool-register

Register new feefi pool

pool-policy-updater

Update pool policy

pool-deposit

Deposit tokens to pool

pool-withdraw

Withdraw tokens from pool

pool-register
pool-register 명령어는 컨트랙트 계정에 새로운 토큰 쌍 pool을 등록하기 위한 operation을 생성해 줍니다.
명령어를 제대로 실행하기 위해서는 일반 계정뿐만이 아니라 컨트랙트 계정도 준비해야 합니다.
$ ./mitum seal pool-register --network-id=NETWORK-ID-FLAG <privatekey> <sender> <pool> <feefipool-income-cid> <feefipool-outlay-cid> <initial-fee> <currency-id>
EXAMPLE
예를 들어, 새로운 풀을 생성하기 위한 과정은 다음과 같습니다.
ac0: pool owner
ca1: target contract account
income cid: PEN
outlay cid: MCC
pool fee: 1000
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ CA1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ INCOME_ID=PEN

$ OUTLAY_ID=MCC

$ CURRENCY_ID=PEN

$ ./mn seal pool-register --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CA1_ADDR $INCOME_ID $OUTLAY_ID 1000 $CURRENCY_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "CNF4tXBZYBN165R4TJBD9fU1eioSM6RkcpP4GXz8yWvg",
    "body_hash": "CmY9uTmSRdbA55vhUeQHfmTB9JoVXqxmDYMTLRJmGx9j",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "381yXZCkYhagFJf8cwNiU1x5C4G9pq6J7WKAaGLamd2ctdrKZ2Rmw76q48wFxRu28dmwtJjcoxdgGcRPzhxrHYrAnJcwnDiU",
    "signed_at": "2022-09-29T03:34:37.900423Z",
    "operations": [
        {
            "fact": {
                "_hint": "mitum-feefi-pool-register-operation-fact-v0.0.1",
                "hash": "64rjFMjZLMrUc5xzqUSSjZAA8wtdBLaEHfCLL5DmXZnX",
                "token": "MjAyMi0wOS0yOVQwMzozNDozNy44OTk4NTha",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "target": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                "initialfee": "1000",
                "incomecid": "PEN",
                "outlaycid": "MCC",
                "currency": "PEN"
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZAFwTeKWD7USrhfrnEEkULmD2nFRuuGuU663STypsFoKBNPoffk7bExDFCStx7SU9uUgB6iWue8VU7a7XUFdSjWRKKn",
                    "signed_at": "2022-09-29T03:34:37.90014Z"
                }
            ],
            "memo": "",
            "_hint": "mitum-feefi-pool-register-operation-v0.0.1",
            "hash": "EspLXHipsoVpsBg43hGyHjtPHxDxEXUph45ThrpKFcrL"
        }
    ]
}
pool-policy-updater
pool-policy-updater 명령어는 이름 그대로 pool 정책을 업데이트하기 위한 명령어입니다.
$ ./mitum seal pool-policy-updater --network-id=NETWORK-ID-FLAG <privatekey> <sender> <pool> <feefipool-income-cid> <feefipool-outlay-cid> <fee> <currency-id>
EXAMPLE
예를 들어 pool 정책을 업데이트하기 위한 과정은 다음과 같습니다.
ac0: pool owner
ca1: target contract account (pool)
income cid: PEN
outlay cid: MCC
pool fee: 1000
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ CA1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ INCOME_ID=PEN

$ OUTLAY_ID=MCC

$ CURRENCY_ID=PEN

$ ./mn seal pool-policy-updater --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CA1_ADDR $INCOME_ID $OUTLAY_ID 100 $CURRENCY_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "2JifrJrATSeZ4DLR93SASMRfYPaBtzRDTKTDnMBo7n2o",
    "body_hash": "GTARF3Aa5N2udRryex6mrNQaFGo8PmTvE9jASZXzKJab",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "381yXYtNVGfFErRKJptsxMyus1XZw7gfp4kbFKdUeruacsdWHmRaFzGVcVNunyNmj3GKsgqccSWvWg9vJWfWGCFcpPJFfKmA",
    "signed_at": "2022-09-29T03:43:37.455156Z",
    "operations": [
        {
            "_hint": "mitum-feefi-pool-policy-updater-operation-v0.0.1",
            "hash": "3HW64V3dkRVUvYHFt9p5aokKb3hThZvmZyDuHvFqCCzC",
            "fact": {
                "_hint": "mitum-feefi-pool-policy-updater-operation-fact-v0.0.1",
                "hash": "3rzZZYGHBpFAt4ERPCDbWcZpnLTfDUam9Squ5vwpmwMU",
                "token": "MjAyMi0wOS0yOVQwMzo0MzozNy40NTQ4MDda",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "target": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                "fee": "100",
                "incomecid": "PEN",
                "outlaycid": "MCC",
                "currency": "PEN"
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZFzjsGsEWraLdWR3ypikpfBjZnPXwoetcnN1jiuzNCC8RVRbmzATeymQQzfdzg2NUHFV4s9B7MjSKZGH7DU8cZ9Eeaa",
                    "signed_at": "2022-09-29T03:43:37.454903Z"
                }
            ],
            "memo": ""
        }
    ]
}
deposit-pool
deposit-pool 명령어는 pool에 토큰을 예치하기 위한 명령어입니다.
$ ./mitum seal deposit-pool --network-id=NETWORK-ID-FLAG <privatekey> <sender> <pool-address> <income-cid> <outlay-cid> <currency-amount>
EXAMPLE
예를 들어, 특정 pool에 토큰을 예치하기 위한 과정은 다음과 같습니다.
ac0: general account
ca1: target contract account (pool)
income cid: PEN
outlay cid: MCC
deposit amount: 1000
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ CA1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ INCOME_ID=PEN

$ OUTLAY_ID=MCC

$ ./mn seal deposit-pool --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CA1_ADDR $INCOME_ID $OUTLAY_ID 1000 --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "62g4Lm6g5trSKMgX69h6x3uWVrecX5nxuSCDoRrZMDvN",
    "body_hash": "7Nre3WrUrbz34THfeD5sfxXYuNaQt15YEJUswfM2N2Kc",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "AN1rKvtcm39tLWjZvdero5eucr2rHN36UCKxuvjcJ2BFBVBEfD2szo8igaCRP5v8hQeM85zLPEtsTzmreVLjSRNRPYr7sBdAL",
    "signed_at": "2022-09-29T05:19:17.776578Z",
    "operations": [
        {
            "_hint": "mitum-feefi-pool-deposits-operation-v0.0.1",
            "hash": "BfnEsBGrCSvy16mPWBmuSHdphUwJJM4RZ22F6TBKQwmy",
            "fact": {
                "_hint": "mitum-feefi-pool-deposits-operation-fact-v0.0.1",
                "hash": "99UQkedTVajjdK3nvTaxpSyiWbqBXadzNagoQVVcmUcH",
                "token": "MjAyMi0wOS0yOVQwNToxOToxNy43NzY0Nlo=",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "pool": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                "incomecid": "PEN",
                "outlaycid": "MCC",
                "amount": "1000"
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZUCwW43whDh8e2t1SEMt2Ug8CjQq2CfgJmuKRoNWZz4M2beUYNkJYR6mdemhjh8M7JNrTTedrWvuZnqkXnaHGxix2nZ",
                    "signed_at": "2022-09-29T05:19:17.776566Z"
                }
            ],
            "memo": ""
        }
    ]
}
withdraw-pool
withdraw-pool 명령어는 pool에 예치한 토큰을 인출하기 위한 명령어입니다.
$ ./mitum seal withdraw-pool --network-id=NETWORK-ID-FLAG <privatekey> <sender> <pool> <income-cid> <outlay-cid> <currency-amount> ...
EXAMPLE
예를 들어 pool로부터 토큰을 인출하기 위한 과정은 다음과 같습니다.
ac0: general account
ca1: target contract account (pool)
income cid: PEN
outlay cid: MCC
withdraw amount: PEN,1000
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ CA1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ INCOME_ID=PEN

$ OUTLAY_ID=MCC

$ ./mn seal withdraw-pool --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CA1_ADDR $INCOME_ID $OUTLAY_ID $INCOME_ID,1000 --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "CH1UGmJXnFSrAvTb6gwUutXmDVveZanUVfaHawoanNDc",
    "body_hash": "52Hd9Cw6oQRCzuPB84P4BQ99oC8NcKJWrWuWnLrDLWte",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "381yXYfZEv6t8nQUKsA2GEZ6Q23xy7YjHHSf41tv5xN4yuukXnErjrHQHjrniUhKKRmxnLFFfK98yNqgKarLNvHFFvpdhinA",
    "signed_at": "2022-09-29T05:26:19.42738Z",
    "operations": [
        {
            "_hint": "mitum-feefi-pool-withdraw-operation-v0.0.1",
            "hash": "2J6vKTXc4y5hSbw2XQYFLfzRoydRA5VA34DSKTDX9pWH",
            "fact": {
                "_hint": "mitum-feefi-pool-withdraw-operation-fact-v0.0.1",
                "hash": "7bmHTxhZieuGFo5LDg7dVjz1bcov5BWoZpvLVtU4ktb2",
                "token": "MjAyMi0wOS0yOVQwNToyNjoxOS40MjcyNTZa",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "pool": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                "incomecid": "PEN",
                "outlaycid": "MCC",
                "amounts": [
                    {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "1000",
                        "currency": "PEN"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZUfYx8mVMa8HQUqL6GiZn6xszPaxCSVg71vKgEPQvq5ZBH4oevwhtrAxcN2Wb5xYZeYtF8k54wbepTxYMg3YTXHyuHB",
                    "signed_at": "2022-09-29T05:26:19.427363Z"
                }
            ],
            "memo": ""
        }
    ]
}

nft

이 모델은 다음과 같은 operation 생성을 지원합니다.

Operations for NFT Collection

collection-register

Register new nft collection

collection-policy-updater

Update nft collection

Operations for NFT

mint

Mint new nft

sign

Sign nft as creator or copyrighter

transfer

Transfer nft

burn

Burn(Deactivate) nft

Operations for Delegation of Authority

delegate

Delegation of authority to nfts of collection

approve

Delegation of authority to any one nft

collection-register
collection-register 은 컨트랙트 계정에 새로운 NFT 컬랙션 디자인을 등록하기 위한 명령어입니다.
이 명령어를 제대로 실행하기 위해서는 일반 계정과 컨트랙트 계정을 모두 준비해야 합니다.
$ ./mitum seal collection-register --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency> <target> <symbol> <name> <royalty>
EXAMPLE
예를 들어, 새로운 NFT 컬랙션을 등록하기 위한 방법은 다음과 같습니다.
ac0: collection owner
ca1: target contract account
collection: Crazy Protocon / CPRT / https://protocon.io/api/collection/CPRT
collection royalty: 10
whitelist: [ ac0 ]
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ CA1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ CURRENCY_ID=PEN

$ COLLECTION_SYMBOL="CPRT"

$ COLLECTION_NAME="Crazy Protocon"

$ COLLECTION_URI=https://protocon.io/api/collection/CPRT

$ ./mn seal collection-register --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CURRENCY_ID $CA1_ADDR $COLLECTION_SYMBOL $COLLECTION_NAME 10 --white=$AC0_ADDR --uri=$COLLECTION_URI --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "5CQ1o3w8N8pDcYHzSDSkiZ7UwQohUDB16Vvuos6UqMna",
    "body_hash": "FCa3xzPeDeqnQex2JEFFXsMGx4SGsfCKWTJFEbvkeZev",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "AN1rKvtLv7bJDvNoQhWiafxhJf5vqz3fSuYbQ5zvajpVnKfcEcmBW1YpmuqS7JrZUmUaDhy6dH3gMirQVrTwpZxTR8qYiwV25",
    "signed_at": "2022-09-29T05:40:13.457989Z",
    "operations": [
        {
            "_hint": "mitum-nft-collection-register-operation-v0.0.1",
            "hash": "Dd7H7EMeXroow4GqJPUJpgzU8e37c28zBut9RigCrm9c",
            "fact": {
                    "_hint": "mitum-nft-collection-register-operation-fact-v0.0.1",
                    "hash": "FaFoitzYgXGxNcSqMvqnjaqe5csAjTS4STubM9xNZKJk",
                    "token": "MjAyMi0wOS0yOVQwNTo0MDoxMy40NTc4NDFa",
                    "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "form": {
                    "_hint": "mitum-nft-collection-register-form-v0.0.1",
                    "target": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                    "symbol": "CPRT",
                    "name": "Crazy Protocon",
                    "royalty": 10,
                    "uri": "https://protocon.io/api/collection/CPRT",
                    "whites": [
                        "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca"
                    ]
                },
                "currency": "PEN"
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZ369TJvHz9SqgnPquJEhN6gLv5vLoxXem1hUKYkqJRh6qoKAPRsj1GVQm6YZn3HPegvHdnFqo1D1Qe7sR5eXdTVVqr3",
                    "signed_at": "2022-09-29T05:40:13.457979Z"
                }
            ],
            "memo": ""
        }
    ]
}
collection-policy-updater
collection-policy-updater 명령어는 등록된 NFT 컬랙션 디자인의 정책을 업데이트하기 위한 operation을 생성합니다.
$ ./mitum seal collection-register --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency> <target> <symbol> <name> <royalty>
EXAMPLE
예를 들어, 등록된 컬랙션을 업데이트하기 위한 과정은 다음과 같습니다.
ac0: collection owner
ca1: target contract account
collection: Crazy Protocon / CPRT / https://protocon.io/api/collection/CPRT
collection royalty: 10
whitelist: [ ac0 ]
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ CA1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ CURRENCY_ID=PEN

$ COLLECTION_SYMBOL="CPRT"

$ COLLECTION_NAME="Crazy Protocon"

$ COLLECTION_URI=https://protocon.io/api/collection/CPRT

$ ./mn seal collection-register --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CURRENCY_ID $CA1_ADDR $COLLECTION_SYMBOL $COLLECTION_NAME 10 --white=$AC0_ADDR --uri=$COLLECTION_URI --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "5CQ1o3w8N8pDcYHzSDSkiZ7UwQohUDB16Vvuos6UqMna",
    "body_hash": "FCa3xzPeDeqnQex2JEFFXsMGx4SGsfCKWTJFEbvkeZev",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "AN1rKvtLv7bJDvNoQhWiafxhJf5vqz3fSuYbQ5zvajpVnKfcEcmBW1YpmuqS7JrZUmUaDhy6dH3gMirQVrTwpZxTR8qYiwV25",
    "signed_at": "2022-09-29T05:40:13.457989Z",
    "operations": [
        {
            "_hint": "mitum-nft-collection-register-operation-v0.0.1",
            "hash": "Dd7H7EMeXroow4GqJPUJpgzU8e37c28zBut9RigCrm9c",
            "fact": {
                    "_hint": "mitum-nft-collection-register-operation-fact-v0.0.1",
                    "hash": "FaFoitzYgXGxNcSqMvqnjaqe5csAjTS4STubM9xNZKJk",
                    "token": "MjAyMi0wOS0yOVQwNTo0MDoxMy40NTc4NDFa",
                    "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "form": {
                    "_hint": "mitum-nft-collection-register-form-v0.0.1",
                    "target": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                    "symbol": "CPRT",
                    "name": "Crazy Protocon",
                    "royalty": 10,
                    "uri": "https://protocon.io/api/collection/CPRT",
                    "whites": [
                        "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca"
                    ]
                },
                "currency": "PEN"
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZ369TJvHz9SqgnPquJEhN6gLv5vLoxXem1hUKYkqJRh6qoKAPRsj1GVQm6YZn3HPegvHdnFqo1D1Qe7sR5eXdTVVqr3",
                    "signed_at": "2022-09-29T05:40:13.457979Z"
                }
            ],
            "memo": ""
        }
    ]
}
mint
mint 명령어는 NFT 컬랙션에 새로운 NFT를 민팅하기 위한 operation를 생성합니다.
컬랙션의 화이트리스트에 등록된 계정만이 해당 컬랙션에 NFT를 민팅할 수 있습니다.
$ ./mitum seal mint --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency> <collection> <hash> <uri>
EXAMPLE
예를 들어 NFT를 어떤 컬랙션에 민팅하기 위한 과정은 다음과 같습니다.
ac0: whitelisted account
collection symbol: target collection
nft hash: 4nM1L2Z44YztaL
nft uri: https://protocon.io/api/nft/CPRT-00001
creator: ac0
copyrighter: none
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ NETWORK_ID=mitum

$ CURRENCY_ID=PEN

$ COLLECTION_SYMBOL=CPRT

$ NFT_HASH=4nM1L2Z44YztaL

$ NFT_URI=https://protocon.io/api/nft/CPRT-00001

$ ./mn seal mint --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CURRENCY_ID $COLLECTION_SYMBOL $NFT_HASH $NFT_URI --creator=$AC0_ADDR,100 --creator-total=100 --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "6RhSU1dnYuvT3VXbo7ihpeyE9jW89RZhq7WShWxUSH7S",
    "body_hash": "BQEXFyqkXYcd4N4FViHeNTFRRiP3M1nxLykFzBQn9pmx",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "381yXYoAAhGbKADEwBbRx63JuER3Cp6zFXmHeiHiq4bLc9BvuCBBckAekDPQQghQ3TmBEsk2xebwoaSctJTgGK7iTuVnQR66",
    "signed_at": "2022-09-29T06:09:15.659013Z",
    "operations": [
        {
            "_hint": "mitum-nft-mint-operation-v0.0.1",
            "hash": "CMmCnrd8r7hoUgKRbvSNXhuA2nhpc9vvr3BXcQ3pWUm2",
            "fact": {
                "_hint": "mitum-nft-mint-operation-fact-v0.0.1",
                "hash": "2TkApoGoQ6ws886g7M92MWrrZcH39xkDBkuRDcT6vLdu",
                "token": "MjAyMi0wOS0yOVQwNjowOToxNS42NTg4NzVa",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "items": [
                    {
                        "_hint": "mitum-nft-mint-item-v0.0.1",
                        "collection": "CPRT",
                        "form": {
                            "_hint": "mitum-nft-mint-form-v0.0.1",
                            "hash": "4nM1L2Z44YztaL",
                            "uri": "https://protocon.io/api/nft/CPRT-00001",
                            "creators": {
                                "_hint": "mitum-nft-signers-v0.0.1",
                                "total": 100,
                                "signers": [
                                    {
                                        "_hint": "mitum-nft-signer-v0.0.1",
                                        "account": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                                        "share": 100,
                                        "signed": false
                                    }
                                ]
                            },
                            "copyrighters": {
                                "_hint": "mitum-nft-signers-v0.0.1",
                                "total": 0,
                                "signers": []
                            }
                        },
                        "currency": "PEN"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "AN1rKvtjKr13MgqBKC3VTEFL2QhUYU94zCLo3eshV1N9oGH1KxxrsMMGefuKJYZAbcsDBr2kV5HdMVjY1ThXbDsGV6Zwxdbtd",
                    "signed_at": "2022-09-29T06:09:15.659002Z"
                }
            ],
            "memo": ""
        }
    ]
}
sign-nfts
sign-nfts 명령어는 민팅된 NFT에 관련 계정으로서 서명하기 위한 operation를 생성합니다.
여기서 말하는 관련 계정이란 NFT 민팅 시 함께 등록된 창작자와 저작권자 계정을 의미합니다.
$ ./mitum seal sign-nfts --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency> <nft>
EXAMPLE
예를 들어, NFT에 서명하기 위한 과정은 다음과 같습니다.
ac0: related account
target nft: CPRT-00001
option: creator
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ NETWORK_ID=mitum

$ CURRENCY_ID=PEN

$ NFT_ID=CPRT,00001

$ ./mn seal sign-nfts --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CURRENCY_ID $NFT_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "8PkkoofAguZsRc8pLfj7hX7GCeoQgDLDLdjfk8ZsViPF",
    "body_hash": "Fs8MKQs1gkoNLK8ZFMnAMko6PyMhpQ2Tk4EuS9fuh6Yr",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "381yXYuqprX8pDANqerFniRf3yjhSxbBxxwxiYaYyjJLsD8QA33erAaMVZrRijx4er2deJdtRHguARzdCaoikPkdFSqE8d1w",
    "signed_at": "2022-09-29T06:18:03.485899Z",
    "operations": [
        {
            "_hint": "mitum-nft-sign-operation-v0.0.1",
            "hash": "5mSy9YJnSu6MAu69vBrFoGDveQcN4KqjbGFLa2E2mYSm",
            "fact": {
                "_hint": "mitum-nft-sign-operation-fact-v0.0.1",
                "hash": "ENR1r1vgDpRNUj7JioenAUtCbrRBphMDqK9yA7VFAUo4",
                "token": "MjAyMi0wOS0yOVQwNjoxODowMy40ODU3NzVa",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                    "items": [
                    {
                        "_hint": "mitum-nft-sign-item-v0.0.1",
                        "qualification": "creator",
                        "nft": {
                            "_hint": "mitum-nft-nft-id-v0.0.1",
                            "collection": "CPRT",
                            "idx": 1
                        },
                        "currency": "PEN"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXYh1acYk32rVqeim4owg7icKb2qy7V9Sq2dv9f5fC7SXdQMJWr9K8vGdk3WuywoQ81PDeCYfFVdvt86W9GdwGwmENZhL",
                    "signed_at": "2022-09-29T06:18:03.485888Z"
                }
            ],
            "memo": ""
        }
    ]
}
저작권자로서 서명하고자 하는 경우 --qualification=copyrighter 옵션을 사용하세요.
transfer-nfts
transfer-nfts 명령어는 어떤 계정에 NFT의 소유권을 이전하기 위한 operation를 생성합니다.
NFT 소유자뿐만 아니라 대리(agent)/승인(approved) 계정이 이 operation을 전송할 수 있는 권한을 갖고 있습니다.
$ ./mitum seal transfer-nfts --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency> <receiver> <nft>
EXAMPLE
예를 들어, NFT를 전송하기 위한 과정은 다음과 같습니다.
ac0: nft owner
ac1: receiver
target nft: CPRT-00001
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ AC1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ CURRENCY_ID=PEN

$ NFT_ID=CPRT,00001

$ ./mn seal transfer-nfts --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CURRENCY_ID $AC1_ADDR $NFT_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "7v6FZR3s4mGBHvD4TFV2JufL8vfo7offBsapNNw6FGz1",
    "body_hash": "8Zvs6uBc8zLpgdGayyGgyFkQfD8avqBWoKm1ZsUTiZe1",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "381yXYj9S5Va9K4nd3BcCAug4aBaev1ftzZye5KFf9MGMCJucCUZpSNGMtpP4a9kZcyjatH5GfP7kAZYCt4N9EsexrfAnPzM",
    "signed_at": "2022-09-29T06:25:32.460976Z",
    "operations": [
        {
            "_hint": "mitum-nft-transfer-operation-v0.0.1",
            "hash": "2jyBBECZJG8aEUFusUg1SgW37XnMZUH1PkJM1gEuiEa5",
            "fact": {
                "_hint": "mitum-nft-transfer-operation-fact-v0.0.1",
                "hash": "9UWSpSmomhkHzaVGvykTKweGSvMxYGJkSQni2yujfsCp",
                "token": "MjAyMi0wOS0yOVQwNjoyNTozMi40NjA4NjZa",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "items": [
                    {
                        "_hint": "mitum-nft-transfer-item-v0.0.1",
                        "receiver": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                        "nft": {
                            "_hint": "mitum-nft-nft-id-v0.0.1",
                            "collection": "CPRT",
                            "idx": 1
                        },
                        "currency": "PEN"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "AN1rKvtC5RugSHM3YUb4NHkkrnVpAz8Wgv7BurQG2nepYXcmdshyZ89KFHrxC9vppditkhKYMz3jYvuyNZPg1TwtJuSoApLpZ",
                    "signed_at": "2022-09-29T06:25:32.460966Z"
                }
            ],
            "memo": ""
        }
    ]
}
burn
burn 명령어는 NFT를 소각하기 위한 operation을 생성합니다.
NFT 소유자뿐만 아니라 대리(agent)/승인(approved) 계정이 이 operation을 전송할 수 있는 권한을 갖고 있습니다.
$ ./mitum seal burn --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency> <nft>
EXAMPLE
예를 들어, NFT를 소각하기 위한 과정은 다음과 같습니다.
ac0: nft owner
target nft: CPRT-00001
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ NETWORK_ID=mitum

$ CURRENCY_ID=PEN

$ NFT_ID=CPRT,00001

$ ./mn seal burn --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CURRENCY_ID $NFT_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "2cbjue66H6EuaupEPEccGoJcsTuv3D96zDmFcaXSQZAr",
    "body_hash": "34GWZf6YqivGExAjc2tY4sYvxQXg5JQCnnvNxNdxHt8F",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "381yXZSNiYzfQtswgxP6TJgRK9ZFPLhrFbDSi8nFF2MfFpMtP2EUbycxMFPk3yvkCT7cT9YChK8QmgXu64yxJXdhUcSq4VNg",
    "signed_at": "2022-09-29T06:30:44.431107Z",
    "operations": [
        {
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXYrNL1wZqEcSkwBdxuPz922sdVh9T3gb2DhsDHLMN4MVkE1L9JGN8SXuYYXHGG8Vgm1fHh15X5E5sg1f6cXBuyZ3NvS1",
                    "signed_at": "2022-09-29T06:30:44.431097Z"
                }
            ],
            "memo": "",
            "_hint": "mitum-nft-burn-operation-v0.0.1",
            "hash": "B7y5eABzoqzaRW1D16f4a3b7YLNRCgnmiYYauTeMtDqJ",
            "fact": {
                "_hint": "mitum-nft-burn-operation-fact-v0.0.1",
                "hash": "CxRKhLGYoUVJGPA8Bg2G86KVUQXBpm5YYGqKAby1mkGh",
                "token": "MjAyMi0wOS0yOVQwNjozMDo0NC40MzEwMDda",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "items": [
                    {
                        "_hint": "mitum-nft-burn-item-v0.0.1",
                        "nft": {
                            "_hint": "mitum-nft-nft-id-v0.0.1",
                            "collection": "CPRT",
                            "idx": 1
                        },
                        "currency": "PEN"
                    }
                ]
            }
        }
    ]
}
delegate
delegate 는 특정 NFT 컬랙션에 대해 어떤 계정이 소유한 NFT들을 전송하고, 소각할 권한을 다른 계정에 위임하는 operation을 생성합니다.
이때 권한을 받는 계정을 대리(agent) 계정이라고 합니다.
어떤 계정이 타겟 NFT 컬랙션의 NFT를 소유하기 전에 이 operation을 전송하여 미리 대리 계정을 위임해 두는 것도 가능합니다.
$ ./mitum seal delegate --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency> <collection> <agent>
EXAMPLE
예를 들어, 대리 계정을 임명하는 과정은 다음과 같습니다.
ac0: general account
ac1: general/contract account (agent)
collection symbol: CPRT
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ AC1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ CURRENCY_ID=PEN

$ COLLECTION_SYMBOL=CPRT

$ ./mn seal delegate --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CURRENCY_ID $COLLECTION_SYMBOL $AC1_ADDR --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "78bKwrFZiodwFxT29Nk3oUsJbeh38Pk1pQj6qYEvpnGC",
    "body_hash": "468Sb3PGoNKANYUhbUPp5W9xy8LXyQWDqrCxQJeWUsmS",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "AN1rKvsxWoVUzURqLxy47XegwGESDpWW4EZv484ZHz45NuZPNbX479jWsF8sByfEXU4wSAdmF7kqzhHwtEFPX7jfycDQYjnJx",
    "signed_at": "2022-09-29T08:40:15.381075Z",
    "operations": [
        {
            "_hint": "mitum-nft-delegate-operation-v0.0.1",
            "hash": "CXjXqfmbDtDaEvrnRkodBCd33jdWpG4q43SKBy8qm6uD",
            "fact": {
                "_hint": "mitum-nft-delegate-operation-fact-v0.0.1",
                "hash": "D2Re8uEsoan37UypSbkCxWk4jT6y2YqRKjCgnzcAVe5k",
                "token": "MjAyMi0wOS0yOVQwODo0MDoxNS4zODA5Nzha",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "items": [
                    {
                        "_hint": "mitum-nft-delegate-item-v0.0.1",
                        "collection": "CPRT",
                        "agent": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                        "mode": "allow",
                        "currency": "PEN"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "381yXZRNLYMpnRziEWDJamTNCiUFQKCBtgwJ5gGubkhHWkGxtBAgzXQAdXvHnKAZoAHb9f6fAbrMuSWj2EZtNZejnXUujSSV",
                    "signed_at": "2022-09-29T08:40:15.381066Z"
                }
            ],
            "memo": ""
        }
    ]
}
만약 위임을 취소하고 싶다면, --mode=cancel 옵션을 사용하세요.
approve
approve 명령어는 NFT 소유자가 다른 계정에 특정 NFT를 전송하거나 소각할 권한을 위임하는 operation을 생성합니다.
이때 권한을 받는 계정을 승인(approved) 계정이라고 합니다.
NFT의 소유자, 혹은 소유자의 대리 계정이 이 operation의 전송자가 될 수 있습니다.
$ ./mitum seal approve --network-id=NETWORK-ID-FLAG <privatekey> <sender> <currency> <approved> <nft>
EXAMPLE
예를 들어 승인 계정을 임명하기 위한 과정은 다음과 같습니다.
ac0: general account
ac1: general/contract account (approved)
target nft: CPRT-00001
$ AC0_PRV=KwejqURNWCqao3MZZcuchZXotsg7LzcvxBYPdL9XA2V9w44Vf4ZDmpr

$ AC0_ADDR=BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca

$ AC1_ADDR=HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca

$ NETWORK_ID=mitum

$ CURRENCY_ID=PEN

$ NFT_ID=CPRT,1

$ ./mn seal approve --network-id=$NETWORK_ID $AC0_PRV $AC0_ADDR $CURRENCY_ID $AC1_ADDR $NFT_ID --pretty
{
    "_hint": "seal-v0.0.1",
    "hash": "HPyk7y6BNba63nd1uwmg9nmyPZLAjG8NxJwG9jCi9Uu1",
    "body_hash": "EoSmooTisCXHgjSvRuhGw2Y9eXY7SzCpwyyPfWVRmVfq",
    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
    "signature": "AN1rKvtRJTx9GUGUD9BXBBJJfXmD9Z6Lpsjo1sq8D1uRCn4Asc4sEHJ3JPZx39nvBgfHcbymNBgZGbwTez21HHtFb8S7Hd8KN",
    "signed_at": "2022-09-29T08:49:00.776655Z",
    "operations": [
        {
            "hash": "6szCeHzng8KZEApzwemEcGA5jwziW8AEbA7w4eHyis3s",
            "fact": {
                "_hint": "mitum-nft-approve-operation-fact-v0.0.1",
                "hash": "HM8WU5MnShZbdXcwozN4Zn87yvkL1bqpE8zkRqSFghp2",
                "token": "MjAyMi0wOS0yOVQwODo0OTowMC43NzY1Mjla",
                "sender": "BQafCTAUdwbgzoHfPcZf6gMBBnJ5h1vXB8oJ7aHz9gQcmca",
                "items": [
                    {
                        "_hint": "mitum-nft-approve-item-v0.0.1",
                        "approved": "HjyXhhuHAZBGaEw2S5cKZhDwqVc1StbkJMtdgGm3F1dnmca",
                        "nft": {
                            "_hint": "mitum-nft-nft-id-v0.0.1",
                            "collection": "CPRT",
                            "idx": 1
                        },
                        "currency": "PEN"
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "tT9K5Mf22vtaB71VryiZDMj2hhijM7JAhXRHSFg3H2nGmpu",
                    "signature": "AN1rKvsyGJc6hdiZv5JbQyWR7Bf4tDUyCVLWNK2fFbLLYEUUKaxfcv97nNkgdZnypuoRPJsFb46GBqkYUb8QKGxvSJwkbKNAL",
                    "signed_at": "2022-09-29T08:49:00.776643Z"
                }
            ],
            "memo": "",
            "_hint": "mitum-nft-approve-operation-v0.0.1"
        }
    ]
}
NFT의 승인 계정을 초기화하려면, operation의 approved 항목을 NFT의 소유자 주소로 변경하여 operation을 다시 전송하세요.

Lookup Account

Prerequisite

Genesis Account Lookup

  1. 로컬 blockdata에서 제네시스 계정을 확인할 수 있습니다.

$ AC0_ACC_KEY=GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623-mca:account

$ find blockfs -name "*-states-*" -print | xargs -n 1 gzcat | grep '^{' | jq '. | select(.key == "'$AC0_ACC_KEY'") | [ "height: "+(.height|tostring), "state_key: " + .key, "address: " + .value.value.address, .operations, .value.value.keys.keys, .value.value.keys.threshold]'
[
    "height: 2",
    "state_key: GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623-mca:account",
    "address: FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
    [
        "9mc8YEFWC27WEF3VVee1wk4ib5kvWBk1iJ41pWf27Mrc"
    ],
    [
        {
            "_hint": "mitum-currency-key-v0.0.1",
            "weight": 100,
            "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
        }
    ],
    100
]
  • 99999999999999999977 = 99999999999999999999 - (2 create account: 10 * 2) - (2 fee: 1 * 2)

  1. digest api로 제네시스 계정을 확인할 수 있습니다.

$ curl --insecure https://localhost:54320/account/FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca | jq '{_embedded}'
{
    "_embedded": {
        "_hint": "mitum-currency-account-value-v0.0.1",
        "hash": "AHQ4ohzwm7Y9T3f8vH5LTQ2rXKfVg3eazCdyihqsWv8F",
        "address": "FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7Bmca",
        "keys": {
            "_hint": "mitum-currency-keys-v0.0.1",
            "hash": "GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623",
            "keys": [
                {
                    "_hint": "mitum-currency-key-v0.0.1",
                    "weight": 100,
                    "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                }
            ],
            "threshold": 100
        },
        "balance": [
            {
                "_hint": "mitum-currency-amount-v0.0.1",
                "amount": "9999999999999",
                "currency": "MCC2"
            },
            {
                "_hint": "mitum-currency-amount-v0.0.1",
                "amount": "50",
                "currency": "MCC"
            }
        ],
        "height": 10,
        "previous_height": -2
    }
}

참고

mongodb 주소로 확인하는 경우, 주소의 - 이후를 삭제하고 이를 키로 사용하세요.

  • FnuHC5HkFMpr4QABukchEeT63612gGKus3cRK3KAqK7BmcaGkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623-mca

Operation Lookup

operation이 블록에 저장되었는지는 operation의 fact.hash 를 digest API에 요청해 확인할 수 있습니다.
$ FACT_HASH=3fDBD1i6V5VpGxB1di6JGgMPhyWZeWRML8FX4LnYXqJE

$ DIGEST_API="https://127.0.0.1:54320"

$ curl --insecure -v $DIGEST_API/block/operation/$FACT_HASH | jq
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-operation-value-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-operation-value-v0.0.1",
        "hash": "3fDBD1i6V5VpGxB1di6JGgMPhyWZeWRML8FX4LnYXqJE",
        "operation": {
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "AhqQMGZHDCeJDp74aQJ8rEXMC6GgQtpxP3rXnjjP41ui",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "3fDBD1i6V5VpGxB1di6JGgMPhyWZeWRML8FX4LnYXqJE",
                "token": "MjAyMS0wNi0xMFQxNTowMToxMy4wNDA0OTZa",
                "sender": "Gu5xHjhos5WkjGo9jKmYMY7dwWWzbEGdQCs11QkyAhh8mca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLu",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "50",
                                "currency": "MCC"
                            }
                        ]
                    },
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "EuCb6BVafkV1tBLsrMqkxojkanJCM4bvmG6JFUZ4s7XL",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "sdjgo1jJ2kxAxMyBj6qZDb8okZpwzHYE8ZACgePYW4eTmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "50",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                    "signature": "AN1rKvthtCymTu7gv2fSrMhGwqVuK3o24FrDe6GGLzRU8N5SWF62nPs3iKcEjuzwHya6P9JmrNLRF95ri8QTE4NBc66TxhCHm",
                    "signed_at": "2021-06-10T15:01:13.053Z"
                }
            ],
            "memo": ""
        },
        "height": 13,
        "confirmed_at": "2021-06-10T15:01:13.354Z",
        "reason": null,
        "in_state": true,
        "index": 0
    },
    "_links": {
        "block": {
            "href": "/block/13"
        },
        "manifest": {
            "href": "/block/13/manifest"
        },
        "new_account:8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLu": {
            "href": "/account/8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
            "address": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
            "key": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLu"
        },
        "new_account:EuCb6BVafkV1tBLsrMqkxojkanJCM4bvmG6JFUZ4s7XL": {
            "href": "/account/2S252hnemi1oA3UZqEA7dvMSvbd3RA9ut1mgJNxoGW1Pmca",
            "key": "EuCb6BVafkV1tBLsrMqkxojkanJCM4bvmG6JFUZ4s7XL",
            "address": "2S252hnemi1oA3UZqEA7dvMSvbd3RA9ut1mgJNxoGW1Pmca"
        },
        "operation:{hash}": {
            "templated": true,
            "href": "/block/operation/{hash:(?i)[0-9a-z][0-9a-z]+}"
        },
        "block:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "self": {
            "href": "/block/operation/3fDBD1i6V5VpGxB1di6JGgMPhyWZeWRML8FX4LnYXqJE"
        }
    }
}

REST API

Digest API는 노드가 블록체인 데이터를 탐색할 수 있도록 합니다.
지갑이나 블록체인 탐색기와 같은 응용 프로그램에 사용할 수 있습니다.
  • API는 HTTP/2 network protocol를 통해 제공됩니다.

  • 응답 메시지는 HAL 을 따르며 JSON 형식으로 전달됩니다.

  • API 데이터 스토리지는 Mitum Currency의 Configuration 에서 설정할 수 있습니다.

  • Mitum의 메인 스토리지가 사용되거나 별도의 데이터베이스를 사용할 수도 있습니다.

  • 서비스 호스트가 로컬호스트이거나 별도의 파일이 설정되지 않은 경우 HTTP/2에 의해 요구되는 TLS certificates는 무작위의 자체 서명 인증서를 생성합니다.

어떤 문제로 operation이 블록에 저장되지 않은 경우 응답에 의해 이유를 확인할 수 있습니다.

Node

Mitum 노드의 상태를 조회할 수 있는 REST API입니다.

REQUEST URL

METHOD

RESPONSE

/

GET

Node information

Block

Mitum 블록의 상태를 조회할 수 있는 REST API 리스트입니다.

REQUEST URL

METHOD

RESPONSE

/block/manifests

GET

All block manifests

/block/{height}

GET

Block by block height

/block/{height}/manifest

GET

Block manifest by block height

/block/{height}/operations

GET

All operations of block

/block/{block_hash}

GET

Block by block hash

/block/{block_hash}/manifest

GET

Block manifest by block hash

/block/operations

GET

All operations

/block/operation/{fact_hash}

GET

Operation by fact hash

Account

계정 상태를 조회할 수 있는 REST API 리스트입니다.

REQUEST URL

METHOD

RESPONSE

/account/{address}

GET

Latest state of account

/account/{address}/operations

GET

Operations related to account

/accounts?publickey={public_key}

GET

Accounts related to public key

Currency

토큰 상태를 조회할 수 있는 REST API 리스트입니다.

REQUEST URL

METHOD

RESPONSE

/currency

GET

All currencies

/currency/{currency_id}

GET

Currency by currency id

자세한 내용은 Mitum Currency Digest API Docs 를 참고하세요.

Feefi

Feefi pool 상태를 조회할 수 있는 REST API 리스트입니다.

REQUEST URL

METHOD

RESPONSE

/feefi/{pool_id}/pool/{address}

GET

Feefi pool

/feefi/{pool_id}/user/{address}

GET

Feefi user

NFT

NFT와 NFT 컬랙션 상태를 조회할 수 있는 REST API입니다.

REQUEST URL

METHOD

RESPONSE

/account/{address}/nftagent/{collection_symbol}

GET

Agent accounts of the account

/account/{address}/nfts

GET

NFTs the account owns

/nft/collection/{collection_symbol}

GET

Collection Design

/nft/collection/{collection_symbol}/nfts

GET

NFTs in the collection

/nft/{nft_id}

GET

NFT

Operation Builder

operation 구축을 위한 REST API 리스트입니다.

REQUEST URL

METHOD

RESPONSE

/builder/operation

GET

Available Operation types

/builder/operation/fact/template/{fact}

GET

Fact template

/builder/operation/fact

POST {fact}

Operation message from fact

/builder/operation/sign

POST {operation}

Operation with hash from operation

/builder/send

POST {operation/seal}

Broadcast seal

Using Operation Builder

Digest API는 operation 메시지 작성을 도와주는 Operation Builder를 가지고 있습니다. Operation Builder를 사용하면 SDK 없이 operation 메시지를 만들 수 있습니다.

Get Operation Fact Template

Operation Fact Template을 요청해 각 operation 타입에 따른 템플릿을 받을 수 있습니다. 템플릿의 필드값을 수정 해 fact 메시지를 만들 수 있습니다.

METHOD

GET

PATH

/builder/operation/fact/template/{fact_type}

RESPONSE EXAMPLE
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
        "hash": "3Zdg5ZVdNFRbwX5WU7Nada3Wnx5VEgkHrDLVLkE8FMs1",
        "token": "cmFpc2VkIGJ5",
        "sender": "mothermca",
        "items": [
            {
                "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                "keys": {
                    "_hint": "mitum-currency-keys-v0.0.1",
                    "hash": "2TQ8Xn5tdowqkJt8kHWcNj2QKhuNRnnCwiXxFbRbwBWY",
                    "keys": [
                        {
                            _hint": "mitum-currency-key-v0.0.1",
                            "weight": 100,
                            "key": "oRHdEPPrgbfNxUp6TWsC35DmWu1zbLCW9rp41Z8npF8Hmpu"
                        }
                    ],
                    "threshold": 100
                },
                "amounts": [
                    {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "-333",
                        "currency": "xXx"
                    }
                ]
            }
        ]
    },
    "_links": {
        "self": {
            "href": "/builder/operation/fact/template/create-accounts"
        }
    },
    "_extra": {
        "default": {
            "items.keys.keys.key": "oRHdEPPrgbfNxUp6TWsC35DmWu1zbLCW9rp41Z8npF8Hmpu"
            "items.big": "-333",
            "currency": "xXx",
            "token": "cmFpc2VkIGJ5",
            "sender": "mothermca",
        }
    }
}
  • 응답 템플릿 내용 중 _embedded 객체는 fact를 나타냅니다. fact의 내용을 편집해 Build Operation Message에 사용하세요.

create-accounts FACT EXAMPLE
{
    "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
    "hash": "3Zdg5ZVdNFRbwX5WU7Nada3Wnx5VEgkHrDLVLkE8FMs1",
    "token": "cmFpc2VkIGJ5",
    "sender": "mothermca",
    "items": [
        {
            "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
            "keys": {
                "_hint": "mitum-currency-keys-v0.0.1",
                "hash": "2TQ8Xn5tdowqkJt8kHWcNj2QKhuNRnnCwiXxFbRbwBWY",
                "keys": [
                    {
                        _hint": "mitum-currency-key-v0.0.1",
                        "weight": 100,
                        "key": "oRHdEPPrgbfNxUp6TWsC35DmWu1zbLCW9rp41Z8npF8Hmpu"
                    }
                ],
                "threshold": 100
            },
            "amounts": [
                {
                    "_hint": "mitum-currency-amount-v0.0.1",
                    "amount": "-333",
                    "currency": "xXx"
                }
            ]
        }
    ]
}
  • hash 값은 builder에 의해 자동적으로 완성됩니다. 그러므로 따로 편집할 필요가 없습니다.

  • token 는 base64로 인코딩된 문자열을 사용합니다.

  • _hint 는 그대로 사용하세요.

keys 와 key 등록에 대한 자세한 내용은 key 를 참고하세요.

Build Operation Message

생성된 fact 메시지는 json 형식으로 request body로 전달되며 완성된 fact 메시지를 응답값으로 돌려받습니다.
예제에서, keys hash, token, fact hash 값이 변경된 fact 메시지를 돌려받을 것입니다.

METHOD

POST

PATH

/builder/operation/fact

RESPONSE EXAMPLE
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-create-accounts-operation-v0.0.1",
    "_embedded": {
        "hash": "92FXbSdm46iuA7kQuC6ENfi5pd64G1Uiu49A3VmaA8Tu",
        "fact": {
            "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
            "hash": "9ttqrz1bkFNCySVnrhYrxewcVB6mkZWWvBpSPS2fShip",
            "token": "MjAyMS0wNi0xNSAwODo0OTozOS45NDggKzAwMDAgVVRD",
            "sender": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
            "items": [
                {
                    "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                    "keys": {
                        "_hint": "mitum-currency-keys-v0.0.1",
                        "hash": "GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623",
                        "keys": [
                            {
                                "_hint": "mitum-currency-key-v0.0.1",
                                "weight": 100,
                                "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                            }
                        ],
                        "threshold": 100
                    },
                    "amounts": [
                        {
                            "_hint": "mitum-currency-amount-v0.0.1",
                            "amount": "333",
                            "currency": "MCC"
                        }
                    ]
                }
            ]
        },
        "fact_signs": [
            {
                "_hint": "base-fact-sign-v0.0.1",
                "signer": "oRHdEPPrgbfNxUp6TWsC35DmWu1zbLCW9rp41Z8npF8Hmpu",
                "signature": "22UZo26eN",
                "signed_at": "2020-10-08T07:53:26Z"
            }
        ],
        "memo": "",
        "_hint": "mitum-currency-create-accounts-operation-v0.0.1"
    },
    "_links": {
        "self": {
            "href": "/builder/operation/fact"
        }
    },
    "_extra": {
        "default": {
            "fact_signs.signer": "oRHdEPPrgbfNxUp6TWsC35DmWu1zbLCW9rp41Z8npF8Hmpu",
            "fact_signs.signature": "22UZo26eN"
        },
        "signature_base": "hCi8MFOChFusqKx6v0zrsJ8u3tppYUOewadYjwTvDUFtaXR1bQ=="
    }
}
응답 데이터의 fact.hash 값을 확인하세요. fact.hash 값은 fact_sign을 생성하기 위해 사용됩니다.
fact_signs 의 한 fact_sign에서,
  • signer 는 서명을 생성하는데 사용된 키페어의 public key입니다.

  • signaturesigner 에 의해 만들어진 서명입니다.

  • signed_at 는 서명 생성 시각입니다.

Sign Operation Message

signature는 fact의 hash 값을 사용해 만들어지며 이에 대한 fact_sign가 fact_signs 에 추가됩니다.
생성된 fact 메시지는 json 형식으로 request body에 전달되며 operation hash가 추가된 완성된 operation 메시지를 돌려받습니다.

METHOD

POST

PATH

/builder/operation/sign

REQUEST BODY EXAMPLE
{
    "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
    "fact": {
        "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
        "hash": "CDUkHDJB4aC8552QvVCAPk8ZtohSuow67cPZZxqZG7RE",
        "token": "MjAyMS0wMy0yNCAwMjozNzozNC4xNzQgKzAwMDAgVVRD",
        "sender": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
        "items": [
            {
                "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                "keys": {
                    "_hint": "mitum-currency-keys-v0.0.1",
                    "hash": "GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623",
                    "keys": [
                        {
                            "_hint": "mitum-currency-key-v0.0.1",
                            "weight": 100,
                            "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                        }
                    ],
                    "threshold": 100
                },
                "amounts": [
                    {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "333",
                        "currency": "MCC"
                    }
                ]
            }
        ]
    },
    "fact_signs": [
        {
            "_hint": "base-fact-sign-v0.0.1",
            "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
            "signature": "AN1rKvtVhunuSdS8g3KWQ1PFBEP9bzz4sU4Vb3B4JrYyVUF79XwNUrG6AzoVfq6mHsK8W4S5hu7LKjDARfAQeDWwit1GnKXcN",
            "signed_at": "2021-06-16T01:56:14.124268Z"
        }
    ],
    "memo": "",
}
RESPONSE EXAMPLE
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-create-accounts-operation-v0.0.1",
    "_embedded": {
        "fact": {
            "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
            "hash": "CDUkHDJB4aC8552QvVCAPk8ZtohSuow67cPZZxqZG7RE",
            "token": "MjAyMS0wMy0yNCAwMjozNzozNC4xNzQgKzAwMDAgVVRD",
            "sender": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
            "items": [
                {
                    "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                    "keys": {
                        "_hint": "mitum-currency-keys-v0.0.1",
                        "hash": "GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623",
                        "keys": [
                            {
                                "_hint": "mitum-currency-key-v0.0.1",
                                "weight": 100,
                                "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                            }
                        ],
                        "threshold": 100
                    },
                    "amounts": [
                        {
                            "_hint": "mitum-currency-amount-v0.0.1",
                            "amount": "333",
                            "currency": "MCC"
                        }
                    ]
                }
            ]
        },
        "fact_signs": [
            {
                "_hint": "base-fact-sign-v0.0.1",
                "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                "signature": "AN1rKvtVhunuSdS8g3KWQ1PFBEP9bzz4sU4Vb3B4JrYyVUF79XwNUrG6AzoVfq6mHsK8W4S5hu7LKjDARfAQeDWwit1GnKXcN",
                "signed_at": "2021-06-16T01:56:14.124268Z"
            }
        ],
        "memo": "",
        "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
        "hash": "9pNsg6gkQJoVsB7iqY3udeLVti2Yxgbe4mFkGqzds2AT"
    },
    "_links": {
        "self": {
            "href": "/builder/operation/sign"
        }
    }
}

Broadcast Message to Network

request body를 통해 Operation나 Seal 메시지를 전송하면 네트워크에 이를 브로드캐스팅 할 수 있습니다.
이때, seal의 signer는 digest 노드가 됩니다.
  • operation를 전송한 경우, digest 노드가 서명한 새로운 seal이 생성됩니다.

  • seal을 전송한 경우, digest 노드가 seal에 서명합니다.

METHOD

POST

PATH

/builder/send

REQUEST BODY EXAMPLE
{
    "fact": {
        "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
        "hash": "CDUkHDJB4aC8552QvVCAPk8ZtohSuow67cPZZxqZG7RE",
        "token": "MjAyMS0wMy0yNCAwMjozNzozNC4xNzQgKzAwMDAgVVRD",
        "sender": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
        "items": [
            {
                "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                "keys": {
                    "_hint": "mitum-currency-keys-v0.0.1",
                    "hash": "GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623",
                    "keys": [
                        {
                            "_hint": "mitum-currency-key-v0.0.1",
                            "weight": 100,
                            "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                        }
                    ],
                    "threshold": 100
                },
                "amounts": [
                    {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "333",
                        "currency": "MCC"
                    }
                ]
            }
        ]
    },
    "fact_signs": [
        {
            "_hint": "base-fact-sign-v0.0.1",
            "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
            "signature": "AN1rKvtVhunuSdS8g3KWQ1PFBEP9bzz4sU4Vb3B4JrYyVUF79XwNUrG6AzoVfq6mHsK8W4S5hu7LKjDARfAQeDWwit1GnKXcN",
            "signed_at": "2021-06-16T01:56:14.124268Z"
        }
    ],
    "memo": "",
    "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
    "hash": "9pNsg6gkQJoVsB7iqY3udeLVti2Yxgbe4mFkGqzds2AT"
}
RESPONSE EXAMPLE
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "seal-v0.0.1",
    "_embedded": {
        "_hint": "seal-v0.0.1",
        "hash": "4UvusVw9RYdqxHQz2EzDb6gW6CgoZGPayD1yZBcdSSHW",
        "body_hash": "9AFx2gAqeMveV6ojwUi6HKx19GfbZZggPTGhTS3dDih5",
        "signer": "uGnKHNfh8EtNVXsL4Qu1a655oQuzibK8Tc41TZUHzHqkmpu",
        "signature": "381yXZAzT6LcYUXfTG9Fifc6neDfXDqpjzuGzfqr1LXPMvvtseJKzGSRwdL6jvkHBaVRdGPD4YfrHnp2rbpZEEWRNAePiJBt",
        "signed_at": "2021-06-16T03:06:33.649190888Z",
        "operations": [
            {
                "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
                "hash": "9pNsg6gkQJoVsB7iqY3udeLVti2Yxgbe4mFkGqzds2AT",
                "fact": {
                    "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                    "hash": "CDUkHDJB4aC8552QvVCAPk8ZtohSuow67cPZZxqZG7RE",
                    "token": "MjAyMS0wMy0yNCAwMjozNzozNC4xNzQgKzAwMDAgVVRD",
                    "sender": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
                    "items": [
                        {
                            "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                            "keys": {
                                "_hint": "mitum-currency-keys-v0.0.1",
                                "hash": "GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623",
                                "keys": [
                                    {
                                        "_hint": "mitum-currency-key-v0.0.1",
                                        "weight": 100,
                                        "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                                    }
                                ],
                                "threshold": 100
                            },
                            "amounts": [
                                {
                                    "_hint": "mitum-currency-amount-v0.0.1",
                                    "amount": "333",
                                    "currency": "MCC"
                                }
                            ]
                        }
                    ]
                },
                "fact_signs": [
                    {
                        "_hint": "base-fact-sign-v0.0.1",
                        "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                        "signature": "AN1rKvtVhunuSdS8g3KWQ1PFBEP9bzz4sU4Vb3B4JrYyVUF79XwNUrG6AzoVfq6mHsK8W4S5hu7LKjDARfAQeDWwit1GnKXcN",
                        "signed_at": "2021-06-16T01:56:14.124268Z"
                    }
                ],
                "memo": ""
            }
        ]
    },
    "_links": {
        "self": {
            "href": ""
        },
        "operation:0": {
            "href": "/block/operation/CDUkHDJB4aC8552QvVCAPk8ZtohSuow67cPZZxqZG7RE"
        }
    }
}

Confirming the Success of the Operation

operation이 성공적으로 처리되었는지 api에 fact hash값을 요청하여 확인할 수 있습니다.

METHOD

GET

PATH

/block/operation/{operation_fact_hash}

  • 만약 응답 메시지에서 _embedded.in_state 가 true라면, operation은 블록에 저장됩니다.

  • 만약 _embedded.in_state 가 false라면, operation은 블록에 저장되지 않습니다.

  • 만약 operation이 실패한 경우, 원인은 다음과 같을 수 있습니다.

    1. 토크느 전송 시 sender의 불충분한 잔액

    2. 부정확한 signature

    3. create-account의 amount가 currency의 new-account-min-balance보다 낮을 경우

    4. 기타 등등…

실패한 이유는 _embedded.reason.msg 에서 찾을 수 있습니다.
RESPONSE EXAMPLE
{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-operation-value-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-operation-value-v0.0.1",
        "hash": "CDUkHDJB4aC8552QvVCAPk8ZtohSuow67cPZZxqZG7RE",
        "operation": {
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "9pNsg6gkQJoVsB7iqY3udeLVti2Yxgbe4mFkGqzds2AT",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "CDUkHDJB4aC8552QvVCAPk8ZtohSuow67cPZZxqZG7RE",
                "token": "MjAyMS0wMy0yNCAwMjozNzozNC4xNzQgKzAwMDAgVVRD",
                "sender": "CoXPgSxcad3fRAbp2JBEeGcYGEQ7dQhdZGWXLbTHpwuGmca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "GkswusUGC22R5wmrXWB5yqFm8UN22yHLihZMkMb3z623",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "2Aopgs1nSzNCWLvQx5fkBJCi2uxjYBfN8TqneqFd9DzGcmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "333",
                                "currency": "MCC"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                    "_hint": "base-fact-sign-v0.0.1",
                    "signer": "rcrd3KA2wWNhKdAP8rHRzfRmgp91oR9mqopckyXRmCvGmpu",
                    "signature": "AN1rKvtVhunuSdS8g3KWQ1PFBEP9bzz4sU4Vb3B4JrYyVUF79XwNUrG6AzoVfq6mHsK8W4S5hu7LKjDARfAQeDWwit1GnKXcN",
                    "signed_at": "2021-06-16T01:56:14.124Z"
                }
            ],
            "memo": ""
        },
        "height": 108674,
        "confirmed_at": "2021-06-16T02:26:55.75Z",
        "reason": {
            "_hint": "base-operation-reason-v0.0.1",
            "msg": "state, \"9g4BAB8nZdzWmrsAomwdvNJU2hA2psvkfTQ5XdLn4F4r-mca:account\" does not exist",
            "data": null
        },
        "in_state": false,
        "index": 0
    },
    "_links": {
        "manifest": {
            "href": "/block/108674/manifest"
        },
        "operation:{hash}": {
            "templated": true,
            "href": "/block/operation/{hash:(?i)[0-9a-z][0-9a-z]+}"
        },
        "block:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "self": {
            "href": "/block/operation/CDUkHDJB4aC8552QvVCAPk8ZtohSuow67cPZZxqZG7RE"
        },
        "block": {
            "href": "/block/108674"
        }
    }
}

API List

이 페이지는 각 API 경로에 대해 설명합니다.
자세한 내용은 Mitum Currency Digest API Docs 을 방문하세요.

Node Info

/
  • 네트워크의 노드 정보를 반환합니다.

PATH

METHOD

/

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "node-info-v0.0.1",
    "_embedded": {
        "_hint": "node-info-v0.0.1",
        "node": {
            "_hint": "base-node-v0.0.1",
            "address": "node4sas",
            "publickey": "21im86HvT3aC4p23AExN7PKRD3RF1GR8cD3E95iEJHhNKmpu"
        },
        "network_id": "bWl0dW0=",
        "state": "CONSENSUS",
        "last_block": {
            "_hint": "block-manifest-v0.0.1",
            "hash": "7KjDLJMMzKw6RtfwjoZZ75rcab15mn6ASjQbGjotX1NW",
            "height": 1622504,
            "round": 0,
            "proposal": "H9ztzWj46ayufSvBXjdNXo7Xs3q2DK8nj9exaMPo1iyt",
            "previous_block": "JeT7t26J279p3EWq1S1yAEdXUqu4EYZa9tprT9nkMCy",
            "block_operations": null,
            "block_states": null,
            "confirmed_at": "2022-02-03T04:47:01.355363841Z",
            "created_at": "2022-02-03T04:47:01.361237906Z"
        },
        "version": "v0.0.1-stable-383cf0c-20211224",
        "policy": {
            "interval_broadcasting_accept_ballot": 1000000000,
            "timespan_valid_ballot": 60000000000,
            "max_operations_in_seal": 10,
            "interval_broadcasting_proposal": 1000000000,
            "wait_broadcasting_accept_ballot": 1000000000,
            "interval_broadcasting_init_ballot": 1000000000,
            "network_connection_timeout": 3000000000,
            "suffrage": "{\"cache_size\":10,\"number_of_acting\":1,\"type\":\"\"}",
            "threshold": 100,
            "max_operations_in_proposal": 100,
            "timeout_waiting_proposal": 5000000000
        },
        "suffrage": [
            {
                "address": "node4sas",
                "publickey": "21im86HvT3aC4p23AExN7PKRD3RF1GR8cD3E95iEJHhNKmpu",
                "conninfo": {
                    "_hint": "http-conninfo-v0.0.1",
                    "url": "https://3.35.171.179:54321",
                    "insecure": true
                }
            }
        ],
        "conninfo": {
            "_hint": "http-conninfo-v0.0.1",
            "url": "https://3.35.171.179:54321",
            "insecure": true
        }
    },
    "_links": {
        "block:{hash}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "currency:{currencyid}": {
            "templated": true,
            "href": "/currency/{currencyid:.*}"
        },
        "block:current": {
            "href": "/block/1622504"
        },
        "block:current-manifest": {
            "href": "/block/1622504/manifest"
        },
        "block:manifest:{hash}": {
            "templated": true,
            "href": "/block/{hash:(?i)[0-9a-z][0-9a-z]+}/manifest"
        },
        "block:next": {
            "href": "/block/1622505"
        },
        "block:prev": {
            "href": "/block/1622503"
        },
        "self": {
            "href": "/"
        },
        "currency": {
            "href": "/currency"
        },
        "block:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "block:manifest:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}/manifest"
        }
    }
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}

Block

/block/manifests
  • 네트워크의 모든 블록 manifest를 반환합니다.

PATH

METHOD

/block/manifests

GET

Query

Example

offset

manifests after offset - block height

2

reverse

manifests by reverse order

1 (true)

  • offset: integer; block height

  • reverse: boolean; use 1 for true

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_embedded": [
        {
            "_hint": "mitum-currency-hal-v0.0.1",
            "hint": "block-manifest-v0.0.1",
            "_embedded": {
                "_hint": "block-manifest-v0.0.1",
                "hash": "F3qqMUDjofiLkftSSHn4N6uZYBppQzc48iKs8Aqupe9b",
                "height": 1,
                "round": 0,
                "proposal": "34VNRjGW3TqrQ455dyqoKp1EDUeAvu3VfnyLu3aZDcur",
                "previous_block": "6AMoeUTpDfF2Vs73HRWRCVfkqnVLs6gSwUpXYbJzDmAV",
                "block_operations": null,
                "block_states": null,
                "confirmed_at": "2021-12-26T04:22:10.627Z",
                "created_at": "2021-12-26T04:22:10.639Z"
            },
            "_links": {
                "next": {
                    "href": "/block/2/manifest"
                },
                "block": {
                    "href": "/block/1"
                },
                "block:{height}": {
                    "templated": true,
                    "href": "/block/{height:[0-9]+}"
                },
                "block:{hash}": {
                    "href": "/block/{height:[0-9]+}",
                    "templated": true
                },
                "manifest:{height}": {
                    "templated": true,
                    "href": "/block/{height:[0-9]+}/manifest"
                },
                "manifest:{hash}": {
                    "templated": true,
                    "href": "/block/{hash:(?i)[0-9a-z][0-9a-z]+}/manifest"
                },
                "self": {
                    "href": "/block/1/manifest"
                },
                "alternate": {
                    "href": "/block/F3qqMUDjofiLkftSSHn4N6uZYBppQzc48iKs8Aqupe9b/manifest"
                }
            }
        },
        ...
    ],
    "_links": {
        "next": {
        "href": "/block/manifests?offset=10"
        },
        "reverse": {
        "href": "/block/manifests?reverse=1"
        },
        "self": {
        "href": "/block/manifests?offset=0"
        }
    }
}
  • 404 (No more manifests)

더 이상 manifest가 없을 경우, 404 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "manifests not found",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/block/{height}
  • block height 로 검색한 블록의 블록 정보를 반환합니다.

PATH

METHOD

/block/{height}

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_links": {
        "self": {
            "href": "/block/5"
        },
        "manifest:{hash}": {
            "templated": true,
            "href": "/block/{hash:(?i)[0-9a-z][0-9a-z]+}/manifest"
        },
        "prev": {
            "href": "/block/4"
        },
        "current": {
            "href": "/block/5"
        },
        "current-manifest": {
            "href": "/block/5/manifest"
        },
        "block:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "block:{hash}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "manifest:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}/manifest"
        },
        "next": {
            "href": "/block/6"
        }
    }
}
  • 400 (block not found)

요청한 block height가 잘못된 경우, 400 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "title": "bad request; invalid height found for block by height: strconv.ParseInt: parsing \"...\": value out of range",
    "detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/block/{height}/manifest
  • block height 로 검색한 블록의 블록 manifest를 반환합니다.

PATH

METHOD

/block/{height}/manifest

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "block-manifest-v0.0.1",
    "_embedded": {
        "_hint": "block-manifest-v0.0.1",
        "hash": "9zVqaLhLngT8gmTUXfRNLo7WxGQBYoZkYw4NSDrKTrvX",
        "height": 222,
        "round": 0,
        "proposal": "66yixQwnHwBaJ4qDfpwsTa2tBgDGXYHGT1Nta7jD24S1",
        "previous_block": "CyPXbZUAhRb5dH2cJHJtfw51H73NwLSkyz1Ad7iWrpDc",
        "block_operations": null,
        "block_states": null,
        "confirmed_at": "2021-12-26T04:29:44.869Z",
        "created_at": "2021-12-26T04:29:44.877Z"
    },
    "_links": {
        "alternate": {
            "href": "/block/9zVqaLhLngT8gmTUXfRNLo7WxGQBYoZkYw4NSDrKTrvX/manifest"
        },
        "next": {
            "href": "/block/223/manifest"
        },
        "block": {
            "href": "/block/222"
        },
        "block:{hash}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "manifest:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}/manifest"
        },
        "manifest:{hash}": {
            "templated": true,
            "href": "/block/{hash:(?i)[0-9a-z][0-9a-z]+}/manifest"
        },
        "block:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "self": {
            "href": "/block/222/manifest"
        }
    }
}
  • 400 (manifest not found)

요청한 block height가 잘못되었을 경우, 400 를 반환합니다.
{
    "title": "invalid height found for manifest by height",
    "detail": "...",
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others"
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/block/{height}/operations
  • block height 로 검색한 블록의 모든 operation을 반환합니다.

PATH

METHOD

/block/{height}/operations

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_embedded": [
        {
            "_hint": "mitum-currency-hal-v0.0.1",
            "hint": "mitum-currency-operation-value-v0.0.1",
            "_embedded": {
                "_hint": "mitum-currency-operation-value-v0.0.1",
                "hash": "FXRvh8ovbAJdmwdz66gtgb1EJSAaSZkA5TadV8KD1oGs",
                "operation": {
                    "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
                    "hash": "EikTtWw8izGuaAWbu8dP7PRKpc5Ri6qYzPxaxaD7fr2r",
                    "fact": {
                        "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                        "hash": "FXRvh8ovbAJdmwdz66gtgb1EJSAaSZkA5TadV8KD1oGs",
                        "token": "MjAyMS0xMi0yN1QwNzo1ODo1My4zMDE3NjcrMDA6MDA=",
                        "sender": "5om5ZuSsqjEj7CxoF1VyLLJYhQoCwBPjUciy9gu8dh8hmca",
                        "items": [
                            {
                                "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                                "keys": {
                                    "_hint": "mitum-currency-keys-v0.0.1",
                                    "hash": "C7ntk12BMkjpBoita2qf6USE45moRmLcrpUXn2FxCB31",
                                    "keys": [
                                        {
                                            "_hint": "mitum-currency-key-v0.0.1",
                                            "weight": 100,
                                            "key": "2BfVL17JezsZjsYx3PzXW9aRzERFA4F2Hnj1bFK7akXhAmpu"
                                        }
                                    ],
                                    "threshold": 100
                                },
                                "amounts": [
                                    {
                                        "_hint": "mitum-currency-amount-v0.0.1",
                                        "amount": "100",
                                        "currency": "MCC"
                                    }
                                ]
                            }
                        ]
                    },
                    "fact_signs": [
                        {
                            "_hint": "base-fact-sign-v0.0.1",
                            "signer": "p4nHuxamW5HQZQd1mpkMqsHCbnnwdjWZ9c21eF2eKdLrmpu",
                            "signature": "AN1rKvtMWpbB3qLou12rkGVXxJxW4kYitEYkagNQJ4QWCYgNYSrLvsxDkLMxRfW2Do9KhkvzPVrr3r48YPN775yiJiMiyGx5m",
                            "signed_at": "2021-12-27T07:58:53.323Z"
                        }
                    ],
                    "memo": ""
                },
                "height": 48480,
                "confirmed_at": "2021-12-27T08:01:54.507Z",
                "reason": {
                    "_hint": "base-operation-reason-v0.0.1",
                    "msg": "; state, \"5om5ZuSsqjEj7CxoF1VyLLJYhQoCwBPjUciy9gu8dh8hmca:account\" does not exist",
                    "data": null
                },
                "in_state": false,
                "index": 0
            },
            "_links": {
                "block": {
                    "href": "/block/48480"
                },
                "manifest": {
                    "href": "/block/48480/manifest"
                },
                "self": {
                    "href": "/block/operation/FXRvh8ovbAJdmwdz66gtgb1EJSAaSZkA5TadV8KD1oGs"
                }
            }
        }
    ],
    "_links": {
        "reverse": {
            "href": "/block/48480/operations?reverse=1"
        },
        "next": {
            "href": "/block/48480/operations?offset=0"
        },
        "self": {
            "href": "/block/48480/operations"
        }
    }
}
  • 404 (operations not found)

더 이상 operation이 없거나 operation이 아예 존재하지 않는 경우, 404 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "operations not found",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/block/{block_hash}
  • block hash 로 검색한 블록의 블록 정보를 반환합니다.

PATH

METHOD

/block/{block_hash}

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_links": {
        "manifest": {
            "href": "/block/7tAfifVzxSz3kKzGq9RceKtuVAeFB7E9jvCUnojV3YfM/manifest"
        },
        "manifest:{height}": {
            "href": "/block/{height:[0-9]+}/manifest",
            "templated": true
        },
        "manifest:{hash}": {
            "templated": true,
            "href": "/block/{hash:(?i)[0-9a-z][0-9a-z]+}/manifest"
        },
        "block:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "block:{hash}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "self": {
            "href": "/block/7tAfifVzxSz3kKzGq9RceKtuVAeFB7E9jvCUnojV3YfM"
        }
    }
}
  • 400 (block not found)

block hash가 잘못되었을 경우, 400 를 반환합니다.
{
    "detail": "..."
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "title": "bad request; invalid hash for block by hash: invalid; empty hash"
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/block/{block_hash}/manifest
  • block hash 로 검색한 블록의 블록 manifest를 반환합니다.

PATH

METHOD

/block/{block_hash}/manifest

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "block-manifest-v0.0.1",
    "_embedded": {
        "_hint": "block-manifest-v0.0.1",
        "hash": "7tAfifVzxSz3kKzGq9RceKtuVAeFB7E9jvCUnojV3YfM",
        "height": 1594489,
        "round": 0,
        "proposal": "3uSAcktWpnrB31RBKS35WABEMZDvDTEtvkMCDVLYfjR8",
        "previous_block": "3FiMUXRZTkcPQCcLwN2fhEP8C8xr9QrB4cK4yTentG59",
        "block_operations": "EF2cQGmrzW4AfUeZyEym7UCSbrMkXCcjhUadk2oM5ME2",
        "block_states": "YMyRynoNP11HfX9aMBjbw8bPWR1MVcaczqeLWV4wve8",
        "confirmed_at": "2022-02-02T12:53:44.669Z",
        "created_at": "2022-02-02T12:53:44.684Z"
    },
    "_links": {
        "block": {
            "href": "/block/1594489"
        },
        "manifest:{hash}": {
            "templated": true,
            "href": "/block/{hash:(?i)[0-9a-z][0-9a-z]+}/manifest"
        },
        "block:{height}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "block:{hash}": {
            "templated": true,
            "href": "/block/{height:[0-9]+}"
        },
        "manifest:{height}": {
            "href": "/block/{height:[0-9]+}/manifest",
            "templated": true
        },
        "self": {
            "href": "/block/1594489/manifest"
        },
        "alternate": {
            "href": "/block/7tAfifVzxSz3kKzGq9RceKtuVAeFB7E9jvCUnojV3YfM/manifest"
        },
        "next": {
            "href": "/block/1594490/manifest"
        }
    }
}
  • 404 (manifest not found)

block hash가 잘못되었을 경우, 404 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "title": "not found; manifest not found",
    "detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/block/operations
  • 네트워크의 모든 operation들을 반환합니다.

PATH

METHOD

/block/operations

GET

Query

Example

offset

manifests after offset - block height

2

reverse

manifests by reverse order

1 (true)

  • offset: integer; block height

  • reverse: boolean; use 1 for true

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_embedded": [
        {
            "_hint": "mitum-currency-hal-v0.0.1",
            "hint": "mitum-currency-operation-value-v0.0.1",
            "_embedded": {
                "_hint": "mitum-currency-operation-value-v0.0.1",
                "hash": "7rSkwgF6BmLmid13jiBJKaaRtgYXS7rtDBFSuNdUNPeo",
                "operation": {
                    "_hint": "mitum-currency-genesis-currencies-operation-v0.0.1",
                    "hash": "2rtWNNHP15pBcdmmzCjsg45D5KPsqs49YPMRC8AtTJbo",
                    "fact": {
                        "_hint": "mitum-currency-genesis-currencies-operation-fact-v0.0.1",
                        "hash": "7rSkwgF6BmLmid13jiBJKaaRtgYXS7rtDBFSuNdUNPeo",
                        "token": "bWl0dW0=",
                        "genesis_node_key": "21im86HvT3aC4p23AExN7PKRD3RF1GR8cD3E95iEJHhNKmpu",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLu",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "currencies": [
                            {
                                "_hint": "mitum-currency-currency-design-v0.0.1",
                                "amount": {
                                    "_hint": "mitum-currency-amount-v0.0.1",
                                    "amount": "1000000000000000000000000000",
                                    "currency": "PEN"
                                },
                                "genesis_account": null,
                                "policy": {
                                    "_hint": "mitum-currency-currency-policy-v0.0.1",
                                    "new_account_min_balance": "10",
                                    "feeer": {
                                        "_hint": "mitum-currency-fixed-feeer-v0.0.1",
                                        "receiver": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
                                        "amount": "1"
                                    }
                                },
                                "aggregate": "1000000000000000000000000000"
                            },
                            ...
                        ]
                    },
                    "fact_signs": [
                        {
                            "_hint": "base-fact-sign-v0.0.1",
                            "signer": "21im86HvT3aC4p23AExN7PKRD3RF1GR8cD3E95iEJHhNKmpu",
                            "signature": "AN1rKvt3e9wPJjbGEvucwxr7ntUX4oNBvsGmU4QQBFdAv1ToxXdCBqtbpJ7TwuqY1DyTCcS8FBQjJDbYsWpWixTTtXA5y3R5y",
                            "signed_at": "2021-12-26T04:21:22.159Z"
                        }
                    ]
                },
                "height": 0,
                "confirmed_at": "2021-12-26T04:21:23.013Z",
                "reason": null,
                "in_state": true,
                "index": 0
            },
            "_links": {
                "block": {
                    "href": "/block/0"
                },
                "manifest": {
                    "href": "/block/0/manifest"
                },
                "self": {
                    "href": "/block/operation/7rSkwgF6BmLmid13jiBJKaaRtgYXS7rtDBFSuNdUNPeo"
                }
            }
        },
        ...
    ],
    "_links": {
        "reverse": {
            "href": "/block/operations?reverse=1"
        },
        "next": {
            "href": "/block/operations?offset=86472,0"
        },
        "self": {
            "href": "/block/operations"
        }
    }
}
  • 404 (operations not found)

operation이 존재하지 않을 경우, 404 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "operations not found",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/block/operation/{fact_hash}
  • fact hash 로 검색한 operation의 operation 정보를 반환합니다.

PATH

METHOD

/block/operation/{fact_hash}

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-operation-value-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-operation-value-v0.0.1",
        "hash": "CtHUdBrLb5cbrkqorSfudS9o4iVMDNafxKiLHZBArHgU",
        "operation": {
            "_hint": "mitum-currency-fee-operation-v0.0.1",
            "hash": "ByDxnBzr116YvesYsFAdn9LR5bw94YWvVEaEFFZukh6H",
            "fact": {
                "_hint": "mitum-currency-fee-operation-fact-v0.0.1",
                "hash": "CtHUdBrLb5cbrkqorSfudS9o4iVMDNafxKiLHZBArHgU",
                "token": "eVQYAAAAAAA=",
                "amounts": [
                    {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "1",
                        "currency": "PEN"
                    }
                ]
            }
        },
        "height": 1594489,
        "confirmed_at": "2022-02-02T12:53:44.669Z",
        "reason": null,
        "in_state": true,
        "index": 1
    },
    "_links": {
        "block": {
            "href": "/block/1594489"
        },
        "manifest": {
            "href": "/block/1594489/manifest"
        },
        "operation:{hash}": {
            "templated": true,
            "href": "/block/operation/{hash:(?i)[0-9a-z][0-9a-z]+}"
        },
        "block:{height}": {
            "href": "/block/{height:[0-9]+}",
            "templated": true
        },
        "self": {
            "href": "/block/operation/CtHUdBrLb5cbrkqorSfudS9o4iVMDNafxKiLHZBArHgU"
        }
    }
}
  • 400 (operation not found)

fact hash가 잘못되었을 경우, 400 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "title": "invalid hash for operation by hash: invalid; empty hash",
    "detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}

Account

/account/{address}
  • account address 로 검색한 계정의 최종 상태를 반환합니다.

PATH

METHOD

/account/{address}

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-account-value-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-account-value-v0.0.1",
        "hash": "YYWJs2ZEmqvuMHkKco9KwJZL9QUuD9j5QZng5KS4mVR",
        "address": "Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca",
        "keys": {
            "_hint": "mitum-currency-keys-v0.0.1",
            "hash": "Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71y",
            "keys": [
                {
                    "_hint": "mitum-currency-key-v0.0.1",
                    "weight": 50,
                    "key": "kdfdUyAkiG88TVNZ28TV7LoRyLynFzH89btk1ctb9u1Ympu"
                },
                {
                    "_hint": "mitum-currency-key-v0.0.1",
                    "weight": 50,
                    "key": "toPtGPdHCsexeVJcJXykBM14gBEJqc487PmgGVjV3w4vmpu"
                }
            ],
            "threshold": 100
        },
        "balance": [
            {
                "_hint": "mitum-currency-amount-v0.0.1",
                "amount": "10",
                "currency": "CWC"
            }
        ],
        "height": 1198976,
        "previous_height": -2
    },
    "_links": {
        "operations:{offset,reverse}": {
            "templated": true,
            "href": "/account/Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca/operations?offset={offset}&reverse=1"
        },
        "block": {
            "href": "/block/1198976"
        },
        "self": {
            "href": "/account/Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca"
        },
        "operations": {
            "href": "/account/Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca/operations"
        },
        "operations:{offset}": {
            "templated": true,
            "href": "/account/Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca/operations?offset={offset}"
        }
    }
}
  • 404 (account not found)

계정 주소가 잘못되었을 경우, 404 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "title": "not found; account, ... not found",
    "detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/account/{address}/operations
  • account address 로 검색한 계정과 관련된 모든 operation들을 반환합니다.

PATH

METHOD

/account/{address}/operations

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_embedded": [
        {
            "_hint": "mitum-currency-hal-v0.0.1",
            "hint": "mitum-currency-operation-value-v0.0.1",
            "_embedded": {
                "_hint": "mitum-currency-operation-value-v0.0.1",
                "hash": "G57ZwvuAxRA778JGTPz16HSHKhAR6Nb7NegRR2VHNwqd",
                "operation": {
                "fact": {
                    "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                    "hash": "G57ZwvuAxRA778JGTPz16HSHKhAR6Nb7NegRR2VHNwqd",
                    "token": "MjAyMi0wMS0xN1QwNjoxOTo1MS44NTJa",
                    "sender": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
                    "items": [
                        {
                            "_hint": "mitum-currency-create-accounts-multiple-amounts-v0.0.1",
                            "keys": {
                                "_hint": "mitum-currency-keys-v0.0.1",
                                "hash": "CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkf",
                                "keys": [
                                    {
                                        "_hint": "mitum-currency-key-v0.0.1",
                                        "weight": 100,
                                        "key": "kdfdUyAkiG88TVNZ28TV7LoRyLynFzH89btk1ctb9u1Ympu"
                                    }
                                ],
                                "threshold": 100
                            },
                            "amounts": [
                                {
                                    "_hint": "mitum-currency-amount-v0.0.1",
                                    "amount": "100000000000000000000000000",
                                    "currency": "CWC"
                                },
                                ...
                            ]
                        }
                    ]
                },
                "fact_signs": [
                    {
                        "_hint": "base-fact-sign-v0.0.1",
                        "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
                        "signature": "AN1rKvtUWK3qTmQKr613vW5eQm6qt3fRx4wZwEMdecudX8aP9w73KcbVBxuDPGHWLr9j8nL1MJfdSiMiYXNoM7qpsj59N2S14",
                        "signed_at": "2022-01-17T06:19:51.886Z"
                    }
                ],
                "memo": "",
                "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
                "hash": "6XAxmTGfm8AxK9ey242FU3M1Y6pkzgtK2LoEYTjHrASh"
            },
            "height": 910536,
            "confirmed_at": "2022-01-17T06:19:53.617Z",
            "reason": null,
            "in_state": true,
            "index": 0
        },
        "_links": {
            "block": {
                "href": "/block/910536"
            },
            "manifest": {
                "href": "/block/910536/manifest"
            },
            "new_account:CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkf": {
                "key": "CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkf",
                "address": "CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkfmca",
                "href": "/account/CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkfmca"
                },
                "self": {
                    "href": "/block/operation/G57ZwvuAxRA778JGTPz16HSHKhAR6Nb7NegRR2VHNwqd"
                }
            }
        },
        ...
    ],
    "_links": {
        "next": {
            "href": "/account/CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkfmca/operations?offset=1291226,0"
        },
        "reverse": {
            "href": "/account/CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkfmca/operations?reverse=1"
        },
        "self": {
            "href": "/account/CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkfmca/operations"
        },
        "account": {
            "href": "/account/CCxfWi1oErWX7vbxddAsLx8bXSwR1FUbwEkAJcb8Qmkfmca"
        }
    }
}
  • 404 (operations not found)

더 이상 operation이 없거나 operation이 아예 존재하지 않을 경우, 404 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "title": "not found; operations not found",
    "detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/accounts?publickey={public_key}
  • public key 를 하나의 key로서 keys에 포함한 모든 계정들을 반환합니다.

PATH

METHOD

/accounts?publickey={public_key}

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_embedded": [
        {
            "_hint": "mitum-currency-hal-v0.0.1",
            "hint": "mitum-currency-account-value-v0.0.1",
            "_embedded": {
                "_hint": "mitum-currency-account-value-v0.0.1",
                "hash": "YYWJs2ZEmqvuMHkKco9KwJZL9QUuD9j5QZng5KS4mVR",
                "address": "Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca",
                "keys": {
                    "_hint": "mitum-currency-keys-v0.0.1",
                    "hash": "Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71y",
                    "keys": [
                        {
                            "_hint": "mitum-currency-key-v0.0.1",
                            "weight": 50,
                            "key": "kdfdUyAkiG88TVNZ28TV7LoRyLynFzH89btk1ctb9u1Ympu"
                        },
                        {
                            "_hint": "mitum-currency-key-v0.0.1",
                            "weight": 50,
                            "key": "toPtGPdHCsexeVJcJXykBM14gBEJqc487PmgGVjV3w4vmpu"
                        }
                    ],
                    "threshold": 100
                },
                "height": 1198976,
                "previous_height": -2
            },
            "_links": {
                "operations:{offset,reverse}": {
                    "templated": true,
                    "href": "/account/Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca/operations?offset={offset}&reverse=1"
                },
                "block": {
                    "href": "/block/1198976"
                },
                "self": {
                    "href": "/account/Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca"
                },
                "operations": {
                    "href": "/account/Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca/operations"
                },
                "operations:{offset}": {
                    "href": "/account/Aqv9Gn15zM3j79WgzwVe73RVZ4RbSab7UK9vSpRbF71ymca/operations?offset={offset}",
                    "templated": true
                }
            }
        },
        ...
    ],
    "_links": {
        "next": {
            "href": "/accounts?publickey=kdfdUyAkiG88TVNZ28TV7LoRyLynFzH89btk1ctb9u1Ympu&offset=1279558,JLni2ExjGn87UNUro8G7aeiM97M9LGFo8sQfdvGgxk1mca"
        },
        "self": {
            "href": "/accounts?publickey=kdfdUyAkiG88TVNZ28TV7LoRyLynFzH89btk1ctb9u1Ympu"
        }
    }
}
  • 400 (accounts not found)

public key가 잘못된 형식일 경우, 400 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "title": "invalue accounts query: failed to decode publickey, \"...\": failed to decode key.BasePublickey: invalid key; pubkey string is empty",
    "detail": ""
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}

Currency

/currency
  • 네트워크의 모든 currency id들을 반환합니다.

PATH

METHOD

/currency

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_links": {
        "currency:{currencyid}": {
            "href": "/currency/{currencyid:.*}",
            "templated": true
        },
        "self": {
            "href": "/currency"
        },
        "currency:PEN": {
            "href": "/currency/PEN"
        }
    }
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/currency/{currency_id}
  • currency id 로 검색한 currency의 currency 정보를 반환합니다.

PATH

METHOD

/currency/{currency_id}

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-currency-design-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-currency-design-v0.0.1",
        "amount": {
            "_hint": "mitum-currency-amount-v0.0.1",
            "amount": "1000000000000000000000000000",
            "currency": "PEN"
        },
        "genesis_account": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
        "policy": {
            "_hint": "mitum-currency-currency-policy-v0.0.1",
            "new_account_min_balance": "10",
            "feeer": {
                "_hint": "mitum-currency-fixed-feeer-v0.0.1",
                "receiver": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
                "amount": "1"
            }
        },
        "aggregate": "1000000000000000000000000000"
    },
    "_links": {
        "currency:{currencyid}": {
            "templated": true,
            "href": "/currency/{currencyid:.*}"
        },
        "block": {
            "href": "/block/0"
        },500
        "operations": {
            "href": "/block/operation/7rSkwgF6BmLmid13jiBJKaaRtgYXS7rtDBFSuNdUNPeo"
        },
        "self": {
            "href": "/currency/PEN"
        }
    }
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}

Document

/block/documents

PATH

METHOD

/block/documents

GET

/block/document/{document_id}

PATH

METHOD

/block/document/{document_id}

GET

/block/{height}/documents

PATH

METHOD

/block/{height}/documents

GET

/account/{address}/documents

PATH

METHOD

/account/{address}/documents

GET

Feefi

/feefi/{pool_id}/pool/{address}

PATH

METHOD

/feefi/{pool_id}/pool/{address}

GET

/feefi/{pool_id}/user/{address}

PATH

METHOD

/feefi/{pool_id}/user/{address}

GET

NFT

/account/{address}/nftagent/{collection_symbol}

PATH

METHOD

/account/{address}/nftagent/{collection_symbol}

GET

/account/{address}/nfts

PATH

METHOD

/account/{address}/nfts

GET

/nft/collection/{collection_symbol}

PATH

METHOD

/nft/collection/{collection_symbol}

GET

/nft/collection/{collection_symbol}/nfts

PATH

METHOD

/nft/collection/{collection_symbol}/nfts

GET

/nft/{nft_id}

PATH

METHOD

/nft/{nft_id}

GET

Builder

/builder/operation
  • 모든 유효한 operation 타입을 반환합니다.

PATH

METHOD

/builder/operation

GET

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "",
    "_links": {
        "operation-fact:{create-accounts}": {
            "templated": true,
            "href": "/builder/operation/fact/template/create-accounts"
        },
        "operation-fact:{key-updater}": {
            "templated": true,
            "href": "/builder/operation/fact/template/key-updater"
        },
        "operation-fact:{transfers}": {
            "templated": true,
            "href": "/builder/operation/fact/template/transfers"
        },
        "operation-fact:{currency-register}": {
            "href": "/builder/operation/fact/template/currency-register",
            "templated": true
        },
        "self": {
            "href": "/builder/operation"
        }
    }
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/builder/operation/fact/template/{fact}
  • 요청한 operation 타입의 fact 템플릿을 반환합니다.

PATH

METHOD

/builder/operation/fact/template/{fact}

GET

  • {fact} 에 사용 가능한 타입은 /builder/operation 에서 확인할 수 있습니다.

Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
        "hash": "8iBXCwN3q8ZvJJ49iAJEN5ZNAhYAYxV69jDLTB9NyzQW",
        "token": "cmFpc2VkIGJ5",
        "sender": "mothermca",
        "items": [
            {
                "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                "keys": {
                    "_hint": "mitum-currency-keys-v0.0.1",
                    "hash": "DBa8N5of7LZkx8ngH4mVbQmQ2NHDd6gL2mScGfhAEqdd",
                    "keys": [
                        {
                            "_hint": "mitum-currency-key-v0.0.1",
                            "weight": 100,
                            "key": "zzeo6WAS4uqwCss4eRibtLnYHqJM21zhzPbKWQVPttxWmpu"
                        }
                    ],
                    "threshold": 100
                },
                "amounts": [
                    {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "-333",
                        "currency": "xXx"
                    }
                ]
            }
        ]
    },
    "_links": {
        "self": {
            "href": "/builder/operation/fact/template/create-accounts"
        }
    },
    "_extra": {
        "default": {
            "token": "cmFpc2VkIGJ5",
            "sender": "mothermca",
            "items.keys.keys.key": "zzeo6WAS4uqwCss4eRibtLnYHqJM21zhzPbKWQVPttxWmpu",
            "items.big": "-333",
            "currency": "xXx"
        }
    }
}
  • 404 (unknown operation)

만약 요청한 {fact} 가 잘못되었다면, 404 를 반환합니다.
{
    "_hint": "mitum-currency-problem-v0.0.1",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "title": "unknown operation, \"...\"",
    "detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/builder/operation/fact
  • 가짜 fact_sign와 operation hash를 포함한 operation 메시지를 반환합니다.

  • fact hash 는 옳은 값으로 계산되어 채워집니다.

  • 요청 시 유효한 fact 메시지를 사용하세요.

PATH

METHOD

/builder/operation/fact

POST

Request Example
  • 요청 시의 json은 fact 메시지여야 합니다.

  • fact의 hash 값을 채울 필요는 없습니다.

{
    "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
    "hash": "",
    "token": "MjAyMS0wOC0yN1QwNjo1MDowNi41OTZa",
    "sender": "ETox5FKJFknprZv7iJk5KnKmqR9kz7fWTEWkHCaDkad3mca",
    "items": [
        {
            "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
            "keys": {
                "_hint": "mitum-currency-keys-v0.0.1",
                "hash": "yAbsevAtgHBT6BXoxJmL2nPveqd1B6kKp2dfAxnoVb1",
                "keys": [
                    {
                        "_hint": "mitum-currency-key-v0.0.1",
                        "key": "bvdEGTsfaG6W3esdY9PjgjrsariGkhU1i3krVWzPaHtYmpu",
                        "weight": 100
                    }
                ],
                "threshold": 100
            },
            "amounts": [
                {
                    "_hint": "mitum-currency-amount-v0.0.1",
                    "amount": "100",
                    "currency": "MCC"
                }
            ]
        }
    ]
}
Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-create-accounts-operation-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
        "hash": "DJ5eA3wYsE4TZiBM9NrPNVWM8cCuceoZpCUNrSpMNQLa",
        "fact": {
            "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
            "hash": "2SehrkkFaqPDgjD6VyHtiAgBRS5Mc5BMFvK6auALP3Sa",
            "token": "MjAyMS0wOC0yN1QwNjo1MDowNi41OTZa",
            "sender": "ETox5FKJFknprZv7iJk5KnKmqR9kz7fWTEWkHCaDkad3mca",
            "items": [
                {
                    "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                    "keys": {
                        "_hint": "mitum-currency-keys-v0.0.1",
                        "hash": "9dGHYkHV61Nob2UivFHSTrZSYNyjzbZyqvwd2XbQ3w2T",
                        "keys": [
                            {
                                "_hint": "mitum-currency-key-v0.0.1",
                                "weight": 100,
                                "key": "bvdEGTsfaG6W3esdY9PjgjrsariGkhU1i3krVWzPaHtYmpu"
                            }
                        ],
                        "threshold": 100
                    },
                    "amounts": [
                        {
                            "_hint": "mitum-currency-amount-v0.0.1",
                            "amount": "100",
                            "currency": "MCC"
                        }
                    ]
                }
            ]
        },
        "fact_signs": [
            {
                "_hint": "base-fact-sign-v0.0.1",
                "signer": "zzeo6WAS4uqwCss4eRibtLnYHqJM21zhzPbKWQVPttxWmpu",
                "signature": "22UZo26eN",
                "signed_at": "2020-10-08T07:53:26Z"
            }
        ],
        "memo": ""
    },
    "_links": {
        "self": {
            "href": "/builder/operation/fact"
        }
    },
    "_extra": {
        "default": {
            "fact_signs.signer": "zzeo6WAS4uqwCss4eRibtLnYHqJM21zhzPbKWQVPttxWmpu",
            "fact_signs.signature": "22UZo26eN"
        },
        "signature_base": "FW3W9vEA0DQwh6QoRxrjCaSPene+l8l1x7v9LUb59tNtaXR1bQ=="
    }
}
  • 400 (problems in request)

만약 요청한 fact 메시지가 잘못되었거나 유효하지 않은 경우, 400 를 반환합니다.
{
"_hint": "mitum-currency-problem-v0.0.1",
"type": "https://github.com/spikeekips/mitum-currency/problems/others",
"title": "...",
"detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/builder/operation/sign
  • 새로운 operation hash를 가진 operation 메시지를 반환합니다.

  • 새롭게 만들어진 operation hash가 operation hash 값으로 채워집니다.

  • 요청 시의 operation 메시지는 operation hash 값이 비워져있어도 유효합니다.

PATH

METHOD

/builder/operation/sign

POST

Request Example
  • 요청 시의 json은 operation 메시지여야 합니다.

  • hash 필드는 채우지 않아도 됩니다. (하지만 fact hash는 맞는 값으로 채워져있어야 합니다.)

{
    "memo": "",
    "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
    "fact": {
        "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
        "hash": "8yGWvxxQUGUd2tL2EEJSJyDTguXgrDrwwFVAgqnefWp5",
        "token": "MjAyMi0wMi0wM1QwNjoyMTozMi41Njla",
        "sender": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
        "items": [
            {
                "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                "keys": {
                    "_hint": "mitum-currency-keys-v0.0.1",
                    "hash": "GyCVt1JHwrjVmJo3Gjf1wpViDC1sCVjfCY8bEV5aHUrq",
                    "keys": [
                        {
                            "_hint": "mitum-currency-key-v0.0.1",
                            "weight": 100,
                            "key": "hTTVAEnZwaGzs12XLax2M7nY4MAnwykYLA6QpVVEbuuMmpu"
                        }
                    ],
                    "threshold": 100
                },
                "amounts": [
                    {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "1000000000000000000000",
                        "currency": "PEN"
                    }
                ]
            }
        ]
    },
    "hash": "",
    "fact_signs": [
        {
            "_hint": "base-fact-sign-v0.0.1",
            "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
            "signature": "AN1rKvtB4BCAHibpYmUZsiPi2abRDJ91Y5qpYpuZuwS2MH1voVSjxCXHhfuTkqAMJCtgEzGtsFaGkjEt9SQucoCia2KDDqQhm",
            "signed_at": "2022-02-03T06:21:32.575Z"
        }
    ]
}
Response Example
  • 200

{
    "_hint": "mitum-currency-hal-v0.0.1",
    "hint": "mitum-currency-create-accounts-operation-v0.0.1",
    "_embedded": {
        "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
        "hash": "2UimExSvg5YYywaTqzY69TgAYGFEnKvtU5eHCiptZPLP",
        "fact": {
            "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
            "hash": "8yGWvxxQUGUd2tL2EEJSJyDTguXgrDrwwFVAgqnefWp5",
            "token": "MjAyMi0wMi0wM1QwNjoyMTozMi41Njla",
            "sender": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
            "items": [
                {
                    "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                    "keys": {
                        "_hint": "mitum-currency-keys-v0.0.1",
                        "hash": "GyCVt1JHwrjVmJo3Gjf1wpViDC1sCVjfCY8bEV5aHUrq",
                        "keys": [
                            {
                                "_hint": "mitum-currency-key-v0.0.1",
                                "weight": 100,
                                "key": "hTTVAEnZwaGzs12XLax2M7nY4MAnwykYLA6QpVVEbuuMmpu"
                            }
                        ],
                        "threshold": 100
                    },
                    "amounts": [
                        {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "1000000000000000000000",
                        "currency": "PEN"
                        }
                    ]
                }
            ]
        },
        "fact_signs": [
            {
                "_hint": "base-fact-sign-v0.0.1",
                "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
                "signature": "AN1rKvtB4BCAHibpYmUZsiPi2abRDJ91Y5qpYpuZuwS2MH1voVSjxCXHhfuTkqAMJCtgEzGtsFaGkjEt9SQucoCia2KDDqQhm",
                "signed_at": "2022-02-03T06:21:32.575Z"
            }
        ],
        "memo": ""
    },
    "_links": {
        "self": {
            "href": "/builder/operation/sign"
        }
    }
}
  • 400 (problems in request)

요청에 문제가 있다면(예를 들어, 유효하지 않은 operation 메시지 등), 400 를 반환합니다.
{
"_hint": "mitum-currency-problem-v0.0.1",
"type": "https://github.com/spikeekips/mitum-currency/problems/others",
"title": "...",
"detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}
/builder/send
  • seal이나 operation을 네트워크에 반환합니다.

  • 브로드캐스팅에 성공한 경우, 완성된 seal json과 함께 200 을 반환합니다.

  • 하지만, 브로드캐스팅의 성공이 operation 처리의 성공을 보장하지는 않습니다.

PATH

METHOD

/builder/send

POST

Request Example
  • 이 API는 operation과 seal을 모두 브로드캐스팅 할 수 있습니다.

  • operation으로 요청할 경우, operation을 포함한 새로운 seal을 만들어 브로드캐스팅합니다.

  • seal로 요청할 경우, 새롭게 seal에 서명한 뒤 브로드캐스팅합니다.

  • operation

{
    "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
    "hash": "2UimExSvg5YYywaTqzY69TgAYGFEnKvtU5eHCiptZPLP",
    "fact": {
        "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
        "hash": "8yGWvxxQUGUd2tL2EEJSJyDTguXgrDrwwFVAgqnefWp5",
        "token": "MjAyMi0wMi0wM1QwNjoyMTozMi41Njla",
        "sender": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
        "items": [
            {
                "_hint": "mitum-currency-create-accounts-single-amount-v0.0.1",
                "keys": {
                    "_hint": "mitum-currency-keys-v0.0.1",
                    "hash": "GyCVt1JHwrjVmJo3Gjf1wpViDC1sCVjfCY8bEV5aHUrq",
                    "keys": [
                        {
                            "_hint": "mitum-currency-key-v0.0.1",
                            "weight": 100,
                            "key": "hTTVAEnZwaGzs12XLax2M7nY4MAnwykYLA6QpVVEbuuMmpu"
                        }
                    ],
                    "threshold": 100
                },
                "amounts": [
                    {
                        "_hint": "mitum-currency-amount-v0.0.1",
                        "amount": "1000000000000000000000",
                        "currency": "PEN"
                    }
                ]
            }
        ]
    },
    "fact_signs": [
    {
        "_hint": "base-fact-sign-v0.0.1",
        "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
        "signature": "AN1rKvtB4BCAHibpYmUZsiPi2abRDJ91Y5qpYpuZuwS2MH1voVSjxCXHhfuTkqAMJCtgEzGtsFaGkjEt9SQucoCia2KDDqQhm",
        "signed_at": "2022-02-03T06:21:32.575Z"
    }
    ],
    "memo": ""
}
  • seal

{
    "_hint": "seal-v0.0.1",
    "hash": "6DrH1RbJHBoKBRFUo33m8foBNti7gSjKg31pgs8L1Cdz",
    "body_hash": "CjjV3HTbTonfkGZWMeXq6rWgBcf8sgRj74i6YdTjNabn",
    "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
    "signature": "AN1rKvszFHPHZVahb17DCx5dzby8c3UBBeV8R2kzPGMiX8e2dceW8n3LifAaPJAHrTs47hF2xiVeyGcqW99j4rwMR1oH4DNeZ",
    "signed_at": "2022-02-03T06:32:28.022166729Z",
    "operations": [
        {
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "GiFDqiwh9j6eqar1yhGGKiT7m8nRaiCW2KqjiAtJQeuu",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "J2Kr6rXvZmj2ooTcmvDCba2y2QCZ8dJikSwGpkH5gJBv",
                "token": "MjAyMi0wMi0wM1QwNjozMjoyOC4wMjE4MDg2NzNa",
                "sender": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-multiple-amounts-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "9Myzqxx5mHxy8oZL1uhvBFQaqwk3Egejh5AaBKsARZka",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "fGZAe2skLHoQ4rhPxbPvjNSjfcPY9292NVyJWX5m4cGYmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "10000",
                                "currency": "PEN"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                "_hint": "base-fact-sign-v0.0.1",
                "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
                "signature": "AN1rKvtYoYJafJUim5BB5sjid8bxNszGB8kuDgbpARnbeGTgUwp2VpVjXS8kbArUVw4axKNb92ZZ4RXmjZn2enHbEAkb6soGL",
                "signed_at": "2022-02-03T06:32:28.022141041Z"
                }
            ],
            "memo": ""
        }
    ]
}
Response Example
  • 200

{
    "_hint": "seal-v0.0.1",
    "hash": "8xNFCxZ6mwgVLXntD7oXapxDLfVXpPDdcjS8Xb4aFQ6m",
    "body_hash": "A1PWmw93mqYd1VXY2ALQFB6qEB7tKQv8AJp1bkAK75QL",
    "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
    "signature": "AN1rKvsxoy63ZDBRqJpz9ps79HHvZMz8jd4yfeTE4v3YFQT5ajoqsZqUF5sTWmACV9R2naBbtXVXamgtw7pPmpSRbkck6NcdF",
    "signed_at": "2022-02-03T06:35:14.742926621Z",
    "operations": [
        {
            "_hint": "mitum-currency-create-accounts-operation-v0.0.1",
            "hash": "GiFDqiwh9j6eqar1yhGGKiT7m8nRaiCW2KqjiAtJQeuu",
            "fact": {
                "_hint": "mitum-currency-create-accounts-operation-fact-v0.0.1",
                "hash": "J2Kr6rXvZmj2ooTcmvDCba2y2QCZ8dJikSwGpkH5gJBv",
                "token": "MjAyMi0wMi0wM1QwNjozMjoyOC4wMjE4MDg2NzNa",
                "sender": "8iRVFAPiHKaeznfN3CmNjtFtjYSPMPKLuL6qkaJz8RLumca",
                "items": [
                    {
                        "_hint": "mitum-currency-create-accounts-multiple-amounts-v0.0.1",
                        "keys": {
                            "_hint": "mitum-currency-keys-v0.0.1",
                            "hash": "9Myzqxx5mHxy8oZL1uhvBFQaqwk3Egejh5AaBKsARZka",
                            "keys": [
                                {
                                    "_hint": "mitum-currency-key-v0.0.1",
                                    "weight": 100,
                                    "key": "fGZAe2skLHoQ4rhPxbPvjNSjfcPY9292NVyJWX5m4cGYmpu"
                                }
                            ],
                            "threshold": 100
                        },
                        "amounts": [
                            {
                                "_hint": "mitum-currency-amount-v0.0.1",
                                "amount": "10000",
                                "currency": "PEN"
                            }
                        ]
                    }
                ]
            },
            "fact_signs": [
                {
                "_hint": "base-fact-sign-v0.0.1",
                "signer": "cnMJqt1Q7LXKqFAWprm6FBC7fRbWQeZhrymTavN11PKJmpu",
                "signature": "AN1rKvtYoYJafJUim5BB5sjid8bxNszGB8kuDgbpARnbeGTgUwp2VpVjXS8kbArUVw4axKNb92ZZ4RXmjZn2enHbEAkb6soGL",
                "signed_at": "2022-02-03T06:32:28.022141041Z"
                }
            ],
            "memo": ""
        }
    ]
}
  • 400 (problems in request)

요청에 문제가 있는 경우(예를 들어, 잘못된 operastion, seal 등), 400 을 반환합니다.
{
"_hint": "mitum-currency-problem-v0.0.1",
"type": "https://github.com/spikeekips/mitum-currency/problems/others",
"title": "...",
"detail": "..."
}
  • 500

{
    "_hint": "mitum-currency-problem-v0.0.1",
    "title": "....",
    "type": "https://github.com/spikeekips/mitum-currency/problems/others",
    "detail": "...."
}

Javascript

이 페이지는 Javascript로 작성된 SDK에 관한 문서입니다.
자세한 내용은 mitum-js-util 을 참고해주세요.

Get Started

Prerequisite and Requirements
mitum-js-util을 사용하고 빌드하기 위해 npm 혹은 yarn 가 설치되어 있어야 합니다.
이 패키지는 다음 환경에서 개발되었습니다.
$ npm --version
v16.10.0

$ node --version
7.24.0
Installation
  • npm을 사용하면,

$ npm install mitumc
  • yarn을 사용하면,

$ yarn add mitumc
  • git을 사용하면,

$ git clone https://github.com/ProtoconNet/mitum-js-util.git

$ cd mitum-js-util

$ sudo npm install -g

$ cd YOUR_PACKAGE

$ npm link mitumc

Make Your First Operation

이 예제는 mitum-js-utilcreate-account operation을 생성하는 방법에 대해 설명합니다.
key-updatertransfer operation 생성 방법은 Support Operations 에서 확인하세요.
Get Available Account
시작하기 전에, 네트워크에 등록된 계정을 가지고 있어야 합니다.
Mitum에서는 오직 이미 존재하는 계정만이 블록에 저장될 수 있는 새로운 operation을 만들 수 있습니다.
계정은 다음과 같은 요소들로 이루어져있습니다.
1. pairs of (public key, weight); aka `keys`
- public key has suffix `mpu`
- The range of each weight should be in 1 <= weight <= 100
- If an account have single public key, the account is called 'single-sig account', or it's called 'multi-sig account'

1. threshold
- The range of threshold should be in 1 <= threshold <= 100
- The sum of all weights of the account should be over or equal to threshold
아직 아무 계정도 가지고 있지 않다면 다른 계정에 당신의 첫 계정을 만들어 달라 요청해야 합니다.
Get Mitum Keypair 파트에서 계정을 위한 키페어를 생성할 수 있습니다.
(public key, weight)쌍과 threshold를 새 계정 생성을 도와줄 계정 보유자에게 전달하세요.
서명을 위해 계정의 각 공개키에 상응하는 개인키를 기억하고 있어야 합니다. 다른 사람에게 개인키를 알려주지 마세요!
물론 계정 주소 또한 sender 로 사용해야 하기 때문에 기억하고 있어야 합니다.
등록되지 않은 계정으로도 operation을 생성할 수는 있지만 해당 operation들은 브로드캐스팅 이후 처리 거부될 것입니다.
이제 첫 operation을 만들기 위해 다음 장으로 이동하세요.
Create Generator
operation의 대부분의 요소는 Generator 로 생성합니다.
Mitum Currency에 대해서는 Generator.currency 를 사용하세요.
Generator 를 생성할 때, network id 가 필요합니다.
network id 는 네트워크에 따라 다릅니다.
이 페이지에서는 mitum 을 네트워크 id로 가정합니다.
import { Generator } from 'mitumc'

const generator = new Generator('mitum')
const currencyGenerator = generator.currency
Generator 에 대한 더 자세한 내용은 Major Classes 로 이동하여 Generator를 참고하세요.
또한, 네트워크 상에서 사용할 수 있는 등록된 계정을 가지고 있어야 합니다.
이제 새로운 operation을 만들기 위한 준비가 끝났습니다.
Create Operation Item
operation이 실행해야할 모든 것은 operation이 아닌 operation fact에 들어있습니다.
fact는 sender, token 등의 기본적인 정보를 담고 있습니다.
사실, 실제 operation의 지시 사항은 그 중에서도 Item에 들어있습니다.
한 마디로, operation을 위해 item들을 먼저 생성해야 한다는 뜻입니다.
아래 조건에 따라 계정을 생성하려 하는 상황이라고 가정해봅시다.
1. The keys and threshold of the account will be,
    - keys(public key, weight): (kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu, 50), (pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu, 50)
    - threshold: 100

2. The initial balance of the account will be,
    - balance(currency id, amount): (MCC, 10000), (PEN, 20000)
계정이 가지고 있는 키의 수가 2 개이기 때문에, 새로운 계정은 multi-sig 계정이 될 것입니다.
새 계정에 대한 모든 조건이 결정되었으면 아래와 같이 item을 생성하세요.
const key1 = currencyGenerator.key("kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu", 50) // key(pub, weight)
const key2 = currencyGenerator.key("pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu", 50) // key(pub, weight)

const keys = currencyGenerator.keys([key1, key2], 100) // createKeys([key1, key2], threshold)

const amount1 = currencyGenerator.amount("MCC", "10000") // amount(currencyId, amount)
const amount2 = currencyGenerator.amount("PEN", "20000") // amount(currencyId, amount)
const amounts = currencyGenerator.amounts([amount1, amount2]); // createAmounts([amount1, amount2])

const createAccountsItem = currencyGenerator.getCreateAccountsItem(keys, amounts); // createCreateAccountsItem(keys, amounts)
  • 우선, Generator.currency.key(public key, weight) 를 사용해 각 key를 생성합니다..

  • 다음으로 모든 키와 계정 threshold를 Generator.currency.keys(key list, threshold) 로 결합합니다.

  • 그리고, Generator.currency.amount(currencyId, amount) 를 사용해 각 amount를 생성합니다..

  • 다음 Generator.currency.amounts(amount list) 로 모든 amount를 결합합니다.

  • 마지막으로, Generator.currency.getCreateAccountsItem(keys, amounts) 를 사용해 item을 생성하세요.

물론 각 item의 내용을 다음 조건 하에서 사용자화 할 수 있습니다.
- `keys`를 사용하여 생성하는 `Keys`는 key를 10개까지 포함할 수 있습니다.
- item 당 최대 10개의 amount를 가질 수 있기 때문에 `amounts`의 amount list에는 amount를 10개까지 넣을 수 있습니다.
- 게다가, `fact`는 item을 여러 개 포함할 수 있습니다. fact 당 item 개수는 최대 10 개입니다.
Create Operation Fact
fact 는 반드시 items, sender, token, fact hash 를 가져야 합니다.
tokenfact hash 는 SDK가 자동적으로 생성해주므로 걱정하지 않아도 됩니다.
반드시 제공해야할 정보는 itemssender 에 대한 것입니다.
item을 생성하는 방법은 바로 위에서 설명하였습니다.
아래 조건을 만족할 수 있는 계정만 sender 로 사용할 수 있다는 것을 명심하세요.
1. 이미 생성되어 등록된 계정.
2. item의 각 amount에 대해 충분한 잔액을 보유한 계정.
3. 계정의 공개키에 상응하는 개인키(멀티 시그 계정인 경우 모든 개인키들 중 일부)를 알고 있는 계정.
그리고 다음과 같이 fact를 생성하세요!
const senderAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca" // sender's account address; replace with your address
const createAccountsFact = currencyGenerator.getCreateAccountsFact(senderAddress, [createAccountsItem]) // getCreateAccountsFact(sender's address, item list)
만약 다수의 item을 가진 fact를 생성하고 싶다면 Generator.currency.getCreateAccountsFact(sender's address, item list) 의 item list에 item을 모두 넣으세요.
Create Operation
드디어 operation을 생성하기 위한 단계에 도달하였습니다!
준비해야 하는 것은 오직 sender의 개인키입니다. 개인키는 fact에 서명하기 위해 필요합니다.
개인키의 서명은 fact 서명으로서 fact_signs 에 추가됩니다.
fact_signs 의 모든 signer의 weight들의 총합이 sender 의 threshold 이상이어야 합니다.
fact_sign에는 오직 sender 의 개인키의 서명만이 유효합니다.
operation에는 memo 값이 존재하지만 필수적이지는 않습니다. 필요한 내용을 넣어도 괜찮지만 memo 또한 operation hash 값에 영향을 미치기 때문에 주의해야 합니다.
이 예제에서는 sender 가 single-sig 계정이라고 가정합니다. 즉, sender의 계정에는 오직 하나의 키 밖에 없습니다.
만약 sender 가 multi-sig 계정이라면 fact_signs 에 여러 개의 서명을 추가해야 할 수 있습니다.
어떤 키들이 반드시 서명해야 하는지는 계정의 threshold와 각 key의 weight에 달렸습니다.
const senderPrivateKey = "KxD8T82nfwsUmQu3iMXENm93YTTatGFp1AYDPqTo5e6ycvY1xNXpmpr" // sender's private key; replace with your private key

const createAccounts = generator.getOperation(createAccountsFact, "") // getOperation(fact, memo)
createAccounts.addSign(senderPrivateKey); // addSign(private key) add fact signature to fact_signs
operation을 생성하기 위해 Generator.currency.getOperation(fact, memo) 가 아닌 Generator.getOperation(fact, memo) 을 사용해야 한다는 점에 주의하세요.
아쉽지만 하나의 operation에는 하나의 fact만 넣을 수 있습니다.
Create Seal
사실 operation 자체로도 계정을 생성하는 데는 충분합니다.
하지만 종종 여러 개의 operation을 seal로 감싸 전송해야 할 일이 있을 수 있습니다. - 여러 개의 각각 다른 계정으로부터 하나의 계정으로 동시에 송금하는 경우 등
위에 언급한대로 하나의 seal은 여러 개의 operation을 가질 수 있습니다.
seal에 넣을 수 있는 operation의 최대 개수는 노드 정책에 따라 다를 수 있습니다.
따라서 seal을 생성하기 전 하나의 seal에 몇 개의 operation을 넣을 수 있는지 확인해야 합니다.
어쨌든 mitum-js-util을 사용해 seal을 생성하는 것은 간단합니다.
준비해야 하는 것은 Mitum 키 패키지로부터 얻은 개인키입니다.
mpr 타입 접미사가 붙은 어떤 btc compressed wif 형식 키라도 가능합니다.
const anyPrivateKey = "KyK7aMWCbMtCJcneyBZXGG6Dpy2jLRYfx3qp7kxXJjLFnppRYt7wmpr"

const operations = [createAccounts]
const seal = generator.getSeal(anyPrivateKey, operations)
getOperation 의 경우와 같이, 단순히 Generator.getSeal(signer, operation list) 을 사용하세요.
감싸길 원하는 모든 operation을 operation list에 추가하세요.

Support Operations

이 파트에서는 각 operation에 대한 코드 예제를 제공합니다.
mitum-js-util가 지원하는 각 Mitum 모델의 operation은 다음과 같습니다.

Model

Support Operations

Currency

create account, key updater, transfer

Currency Extension

create contract account, withdraw

Document

create document, update document, (sign document)

Feefi

pool register, pool policy updater, pool deposit, pool withdraw

NFT

collection register, collection policy updater, mint, transfer, burn, sign, approve, delegate

Currency
Create Account
create-account 의 예제는 이미 설명했으나 여기서 하나의 코드 블록으로 다시 한 번 소개합니다.
새 계정을 생성하기 위해 다음과 같은 것을 준비해야 합니다.
  • 새로운 계정의 정보: (public key, weight)쌍과 threshold로 이루어진 계정 keys, (currency id, amount) 쌍으로 이루어진 계정 초기 잔액

  • 이미 존재하는 sender의 계정 - 특히 계정 주소와 개인키를 알아야 합니다.

이전에 설명한대로 어떤 개인키가 서명해야 하는지는 threshold와 weight들의 구성에 달렸습니다.
import { Generator } from 'mitumc'

const generator = new Generator('mitum')
const currencyGenerator = generator.currency

const key1 = currencyGenerator.key("kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu", 50)
const key2 = currencyGenerator.key("pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu", 50)

const keys = currencyGenerator.keys([key1, key2], 100)

const amount1 = currencyGenerator.amount("MCC", "10000")
const amount2 = currencyGenerator.amount("PEN", "20000")
const amounts = currencyGenerator.amounts([amount1, amount2]);

const createAccountsItem = currencyGenerator.getCreateAccountsItem(keys, amounts);

const senderAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca"
const createAccountsFact = currencyGenerator.getCreateAccountsFact(senderAddress, [createAccountsItem])

const senderPrivateKey = "KxD8T82nfwsUmQu3iMXENm93YTTatGFp1AYDPqTo5e6ycvY1xNXpmpr"

const createAccounts = generator.getOperation(createAccountsFact, "")
createAccounts.addSign(senderPrivateKey);
자세한 설명은 생략합니다. Make Your First Operation 의 시작 부분을 확인하세요.
Key Updater
이 operation은 말 그대로 계정의 키를 업데이트 하기 위한 것입니다.
예를 들어, 다음과 같은 구성으로 키를 업데이트할 수 있습니다.
- I have an single sig account with keys: (kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu, 100), threshold: 100
- But I want to replace keys of the account with keys: (22ndFZw57ax28ydC3ZxzLJMNX9oMSqAfgauyWhC17pxDpmpu, 50), (22wD5RWsRFAr8mHkYmmyUDzKf6VBNgjHcgc3YhKxCvrZDmpu, 50), threshold: 100
- Then you can use key-updater operation to reach the goal!
single-sig 계정을 multi-sig로 바꾸거나 반대로 multi-sig에서 single-sig로 바꿀 수 있을까요?
물론 가능합니다!
계정 키를 업데이트하기 위해서 다음과 같은 것을 준비해야 합니다.
  • 키를 교체하고자 하는 계정(target)의 정보 - 계정 주소와 개인키; 어떤 개인키가 필요한지는 threshold와 키 weight들에 따라 다를 수 있습니다.

  • 새로운 keys: (public key, weights)쌍들과 threshold

  • 수수료를 지불하려는 currency의 충분한 잔액

create-accounttransferitem operation 생성을 위해 item을 만들어야 하지만 key-updater 는 item이 필요하지 않습니다.
바로 fact를 만드세요.
import { Generator } from 'mitumc'

const generator = new Generator('mitum')
const currencyGenerator = generator.currency

const targetAddress = "JDhSSB3CpRjwM8aF2XX23nTpauv9fLhxTjWsQRm9cJ7umca"
const targetPrivateKey = "KzejtzpPZFdLUXo2hHouamwLoYoPtoffKo5zwoJXsBakKzSvTdbzmpr"

const newPub1 = currencyGenerator.key("22ndFZw57ax28ydC3ZxzLJMNX9oMSqAfgauyWhC17pxDpmpu", 100)
const newPub2 = currencyGenerator.key("22wD5RWsRFAr8mHkYmmyUDzKf6VBNgjHcgc3YhKxCvrZDmpu", 100)
const newKeys = currencyGenerator.keys([newPub1, newPub2], 100)

const keyUpdaterFact = currencyGenerator.getKeyUpdaterFact(targetAddress, "MCC", newKeys) // getKeyUpdaterFact(target address, currency for fee, new keys)

const keyUpdater = generator.getOperation(keyUpdaterFact, "")
keyUpdater.addSign(targetPrivateKey) // only one signature since the account is single-sig
  • 계정의 키를 업데이트한 후에는 이전의 키를 사용할 수 없게 됩니다. 계정의 새로운 키페어의 개인키로 서명해야 합니다.

  • 따라서 네트워크에 key-updater operation을 전송하기 전, 새로운 키들을 기록해두세요.

Transfer
드디어 다른 계정으로 토큰을 송금할 수 있습니다!
다른 operation들과 같이, 다음과 같은 것들을 준비해야 합니다.
  • sender의 계정 정보 - 계정 주소와 개인키

  • 송금할 (currency id, amount) 쌍

create-account 처럼 fact 생성 전 item을 먼저 만들어야 합니다.
operation을 전송하기 전 전송하려는 토큰의 잔액이 충분한지 먼저 확인하세요.
시작하기 전, 다음과 같이 토큰을 전송하려 한다고 가정해 봅시다.
  • 1000000 MCC token

  • 15000 PEN token

그리고 receiver는,
  • CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca

최대 10 (currency id, amount) 쌍이 item 하나에 들어갈 수 있습니다.
또한 최대 10개의 item이 한 fact에 들어갈 수 있습니다. 하지만 각 item의 receiver는 달라야 합니다.
import { Generator } from 'mitumc'

const generator = new Generator('mitum')
const currencyGenerator = generator.currency

const senderPrivateKey = "KzdeJMr8e2fbquuZwr9SEd9e1ZWGmZEj96NuAwHnz7jnfJ7FqHQBmpr"
const senderAddress = "2D5vAb2X3Rs6ZKPjVsK6UHcnGxGfUuXDR1ED1hcvUHqsmca"
const receiverAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca"

const amount1 = currencyGenerator.amount("MCC", "1000000")
const amount2 = currencyGenerator.amount("PEN", "15000")
const amounts = currencyGenerator.amounts([amount1, amount2])

const transfersItem = currencyGenerator.getTransfersItem(receiverAddress, amounts) // getTransfersItem(receiver address, amounts)
const transfersFact = currencyGenerator.getTransfersFact(senderAddress, [transfersItem]) // getTransfersFact(sender address, item list)

const transfers = generator.getOperation(transfersFact, "")
transfers.addSign(senderPrivateKey) // suppose sender is single-sig
Currency Extension
Create Contract Account
이 operation을 전송하여 새로운 컨트랙트 계정을 생성할 수 있습니다.
create-contract-account operation을 생성하기 위한 단계는 create-account와 동일합니다.
컨트랙트 계정과 일반 계정의 차이는 컨트랙트 계정의 경우, 계정 정보에 공개키가 없다는 점입니다.
때문에, 컨트랙트 계정은 operation 전송자가 되어 operation을 전송하거나 시작할 수 없고 다른 계정으로 스스로 토큰을 전송할 수도 없습니다.
컨트랙트 계정의 소유자만이 withdraw operation을 통해 일반 계정으로 토큰을 인출할 수 있습니다.
다음 예는 create-contract-account operation을 생성하는 예제이며, 자세한 설명은 생략되었습니다.
import { Generator } from 'mitumc'

const networkId = 'mitum'
const generator = new Generator(networkId)
const currencyGenerator = generator.currency

const key1 = currencyGenerator.key("kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu", 50)
const key2 = currencyGenerator.key("pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu", 50)

const keys = currencyGenerator.keys([key1, key2], 100)

const amount1 = currencyGenerator.amount("MCC", "10000")
const amount2 = currencyGenerator.amount("PEN", "20000")
const amounts = currencyGenerator.amounts([amount1, amount2]);

const createAccountsItem = currencyGenerator.extension.getCreateContractAccountsItem(keys, amounts);

const senderAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca"
const createAccountsFact = currencyGenerator.extension.getCreateContractAccountsFact(senderAddress, [createAccountsItem])

const senderPrivateKey = "KxD8T82nfwsUmQu3iMXENm93YTTatGFp1AYDPqTo5e6ycvY1xNXpmpr"

const createContractAccounts = generator.getOperation(createContractAccounts, "")
createContractAccounts.addSign(senderPrivateKey);
Withdraw
컨트랙트 계정에 예치된 토큰은 withdraw operation을 통해 컨트랙트 계정의 소유자에게 인출될 수 있습니다.
import { Generator } from 'mitumc';

const generator = new Generator('mitum')
const currencyGenerator = generator.currency

const amount = currencyGenerator.amount("MCC", "100");
const amounts = currencyGenerator.amounts([amount]);

const targetAddress = "2D5vAb2X3Rs6ZKPjVsK6UHcnGxGfUuXDR1ED1hcvUHqsmca";
const withdrawsItem = currencyGenerator.extension.getWithdrawsItem(targetAddress,  amounts);

const senderAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca";
const withdrawsFact = currencyGenerator.extension.getWithdrawsFact(senderAddress, [withdrawsItem])

const senderPrivateKey = "KxD8T82nfwsUmQu3iMXENm93YTTatGFp1AYDPqTo5e6ycvY1xNXpmpr";

const withdraws = generator.getOperation(withdrawsFact, "")
withdraws.addSign(senderPrivateKey)
document, feefi, NFT 모델의 operation을 생성하는 방법은 README 에서 확인할 수 있습니다.

Sign

operation이 정상적으로 블록에 저장되기 위해서는 operation의 서명들이 특정 조건을 만족해야 합니다.
주의해야할 점은,
  • 모든 서명이 계정의 개인키의 서명인가요?

  • 각 signer의 weight들을 모두 합한 값이 계정의 threshold 이상인가요?

물론, 각 operation이 지켜야 할 다른 조건들이 더 있습니다. 하지만 여기서는 (fact)서명에만 집중하겠습니다.
각 키의 weight가 30이고 threshold가 50인 멀티 시그 계정이 있다고 가정해봅시다.
즉, 다음과 같습니다.
  • (pub1, 30)

  • (pub2, 30)

  • (pub3, 30)

  • threshold: 50

이 계정이 operation을 전송하길 원할 때, operation은 서로 다른 signer의 최소 2 개의 fact 서명을 가지고 있어야 합니다.
  1. CASE1: fact signatures signed by pub1’s private key and pub2’s private key

    1. the sum of pub1’s weight and pub2’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  2. CASE2: fact signatures signed by pub2’s private key and pub3’s private key

    1. the sum of pub2’s weight and pub3’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  3. CASE3: fact signatures signed by pub1’s private key and pub3’s private key

    1. the sum of pub1’s weight and pub3’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  4. CASE4: fact signatures signed by pub1’s private key, pub2’s private key, pub3’s private key

    1. the sum of pub1’s weight, pub2’s weight and pub3’s weight: 90

    2. the sum of weights = 90 > threshold = 50

    3. So the operation with these two fact signatures is available

그러므로 조건을 만족하기 위해 각 operation에 여러 개의 signature를 추가해야 합니다. (Operation.addSign(private key) 를 사용하세요.)
CASE4의 경우와 같이 weight들의 총합 >= threshold 조건이 지켜지는 한 모든 개인키로 서명하는 것도 가능합니다.
Add Fact Sign to Operation
operation 생성 시 fact 서명을 추가하는 방법 외에 fact 서명을 추가하는 다른 방법이 하나 더 있습니다.
operation에 새 서명을 추가하기 위해 준비해야 할 것은 다음과 같습니다.
  • 서명할 개인키 - 이 개인키는 계정의 키여야 합니다.

  • JS dictionary 객체 혹은 외부 JSON 파일 형태의 operation

  • Network ID

우선 Generator 처럼 network id 와 함께 Signer 를 생성합니다.
import { Signer } from 'mitumc'

const networkId = "mitum"
const signKey = "L3CQHoKPJnK61LZhvvvfRouvAjVVabx2RQXHHhPHbBssgcewjgNimpr"
const signer = new Signer(networkId, signKey)
그리고, 서명하세요!
const operationJsonPath = "../createAccount.json" // it's an example; replace with your operation path
const operationObject = createAccount.dict() // createAccount is the operation created by Generator.createOperation

const signedFromPath = signer.signOperation(operationJsonPath)
const signedFromObject = signer.signOperation(operationObject)
signedFromPathsignedFromObject 는 결과가 같습니다.
아웃풋인 signed는 mitum-js-util의 Operation 객체가 아닙니다. 단지 dictionary 객체입니다.
한 번에 여러 개의 서명을 추가하길 원한다면 signed - dictionary object에 다른 개인키로 Signer를 다시 만들어 서명해야 합니다.

Details

Get Mitum Keypair
Mitum 키페어 생성 방법을 소개합니다!
시작 전, 중요한 것을 설명하겠습니다.
Mitum의 계정의 주소, 개인키, 공개키는 각자 특별한 타입 접미사를 가지고 있습니다. 그것은 다음과 같습니다.
  • Account Address: mca

  • Private Key: mpr

  • Public Key: mpu

예를 들어, 한 single sign 계정은 다음과 같은 형태를 가집니다.
  • Account Address: 9XyYKpjad2MSPxR4wfQHvdWrZnk9f5s2zc9Rkdy2KT1gmca

  • Private Key: L11mKUECzKouwvXwh3eyECsCnvQx5REureuujGBjRuYXbMswFkMxmpr

  • Public Key: 28Hhy6jwkEHx75bNLmG66RQu1LWiZ1vodwRTURtBJhtPWmpu

키페어를 생성하는 세 가지 방법이 있습니다.
Just Create New Keypair
mitum-js-util가 무작위의 키페어를 생성해줍니다.
getNewKeypair() 를 사용하세요.
import { getNewKeypair } from 'mitumc'

const kp = getNewKeypair() // returns Keypair

kp.getPrivateKey() // KzF4ia7G8in3hm7TzSr5k7cNtx46BdEFTzVdnh82vAopqxJG8rHompr
kp.getPublicKey() // 25jrVNpKr59bYxrWH8eTkbG1iQ8hjvSFKVpfCcDT8oFf8mpu

kp.getRawPrivateKey() // KzF4ia7G8in3hm7TzSr5k7cNtx46BdEFTzVdnh82vAopqxJG8rHo
kp.getRawPublicKey() // 25jrVNpKr59bYxrWH8eTkbG1iQ8hjvSFKVpfCcDT8oFf8mpu
Get Keypair From Your Private Key
이미 개인키를 가지고 있다면 해당 키로부터 키페어를 생성할 수 있습니다.
import { getKeypairFromPrivateKey } from 'mitumc'

const kp = getKeypairFromPrivateKey("Kz5b6UMxnRvgL91UvNMuRoTfUEAUw7htW2z4kV2PEZUCVPFmdbXimpr")

kp.getPrivateKey() // Kz5b6UMxnRvgL91UvNMuRoTfUEAUw7htW2z4kV2PEZUCVPFmdbXimpr
kp.getPublicKey() // 239uA6z7MxkZfwp5zYKZ6eBbRWk38AvxeyzfHGQM8o2H8mpu

kp.getRawPrivateKey() // Kz5b6UMxnRvgL91UvNMuRoTfUEAUw7htW2z4kV2PEZUCVPFmdbXi
kp.getRawPublicKey() //239uA6z7MxkZfwp5zYKZ6eBbRWk38AvxeyzfHGQM8o2H8
Get Keypair from your seed
시드로부터 키페어를 생성할 수도 있습니다. 키페어의 개인키를 기억하지 못하더라도 시드를 통해 복구할 수 있습니다.
문자열 시드 길이는 36 이상이어야 합니다.
import { getKeypairFromSeed } from 'mitumc'

const kp = getKeypairFromSeed("Thelengthofseedshouldbelongerthan36characters.Thisisaseedfortheexample.")

kp.getPrivateKey() // KynL1wNZjuXvZDboEugU4sWKZ6ck5GTMqtv6eod8Q7C4NaB4kfZPmpr
kp.getPublicKey() // fyLbH5cUwNTihaW2YkJkAzeoLvTNTzf98r8dtCkjXbuqmpu

kp.getRawPrivateKey() // KynL1wNZjuXvZDboEugU4sWKZ6ck5GTMqtv6eod8Q7C4NaB4kfZP
kp.getRawPublicKey() // fyLbH5cUwNTihaW2YkJkAzeoLvTNTzf98r8dtCkjXbuq
Get Account Address with Keys
계정 주소를 threshold와 계정의 모든 (public key, weight)쌍을 사용해 알아낼 수 있습니다.
하지만 이 방법은 계정의 threshold나 키가 업데이트 되지 않은 경우에만 사용할 수 있습니다.
예제의 계정 정보는 다음과 같습니다.
  • key1: (vmk1iprMrs8V1NkA9DsSL3XQNnUW9SmFL5RCVJC24oFYmpu, 40)

  • key2: (29BQ8gcVfJd5hPZCKj335WSe4cyDe7TGrjam7fTrkYNunmpu, 30)

  • key3: (uJKiGLBeXF3BdaDMzKSqJ4g7L5kAukJJtW3uuMaP1NLumpu, 30)

  • threshold: 100

import { Generator } from 'mitumc'

const gn = new Generator('mitum').currency

const key1 = gn.key("vmk1iprMrs8V1NkA9DsSL3XQNnUW9SmFL5RCVJC24oFYmpu", 40)
const key2 = gn.key("29BQ8gcVfJd5hPZCKj335WSe4cyDe7TGrjam7fTrkYNunmpu", 30)
const key3 = gn.key("uJKiGLBeXF3BdaDMzKSqJ4g7L5kAukJJtW3uuMaP1NLumpu", 30)

const keys = gn.keys([key1, key2, key3], 100)

const address = keys.address // this is what you want to get!
Major Classes
Generator
Generator 는 각 Mitum 모델의 operation 생성을 도와줍니다.
Generator 를 사용하기 전 network id 를 설정해야 합니다.
  • Mitum Currency: Generator.currency

  • Mitum Currency Extension: Generator.currency.extension

  • Mitum Document: Generator.document

  • Mitum Feefi: Generator.feefi

  • Mitum NFT: Generator.nft

import { Generator } from 'mitumc'

const networkId = 'mitum'
const generator = new Generator(networkId)

const currencyGenerator = generator.currency
const extensionGenerator = generator.currency.extension
const documentGenerator = generator.document
const feefiGenerator = generator.feefi
const nftGenerator = generator.nft
Generator 가 제공하는 모든 메서드는 다음과 같습니다.
/* For Mitum Currency */
Generator.currency.key(key, weight) // 1 <= $weight <= 100
Generator.currency.amount(currencyId, amount) // typeof $amount === "string"
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)

/* For Mitum Currency Extension */
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 */
Generator.document.getCreateDocumentsItem(document, currencyId)
Generator.document.getUpdateDocumentsItem(document, currencyId)
Generator.document.getCreateDocumentsFact(sender, items)
Generator.document.getUpdateDocumentsFact(sender, items)

/* For 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)

/* For 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 Feefi */
Generator.feefi.getPoolRegisterFact(sender, target, initFee, incomeCid, outlayCid, currencyId)
Generator.feefi.getPoolPolicyUpdaterFact(sender, target, fee, incomeCid, outlayCid, currencyId)
Generator.feefi.getPoolDepositsFact(sender, pool, incomeCid, outlayCid, amount)
Generator.feefi.getPoolWithdrawFact(sender, pool, incomeCid, outlayCid, amounts)

/* For 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, currencyId)
Generator.nft.getTransferItem(receiver, nftId, currencyId)
Generator.nft.getBurnItem(nftId, currencyId)
Generator.nft.getApproveItem(approved, nftId, currencyId)
Generator.nft.getDelegateItem(collection, agent, mode, currencyId)
Generator.nft.getSignItem(qualification, nftId, cid)
Generator.nft.getCollectionRegisterFact(sender, form, currencyId)
Generator.nft.getCollectionPolicyUpdaterFact(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)

/* Common */
Generator.getOperation(fact, memo)
Generator.getSeal(signKey, operations)
Signer
Signer 는 이미 생성된 operation에 새로운 fact 서명을 추가할 때 사용합니다.
Generator 와 같이 network id 가 설정되어야 합니다.
서명에 사용할 개인키도 준비해야 합니다.
Signer 는 오직 하나의 메서드를 제공합니다.
Signer.signOperation(operation)
Signer 의 정확한 사용 방법은 ‘Make Your First Operation - Sign’로 돌아가서 확인하세요.
JSONParser
이 클래스는 편의를 위해 개발되었습니다.
Operation 을 내보내거나 JSON 형식으로 출력하기 위해 다른 패키지를 사용하길 원한다면 반드시 mitum-js-util의 JSONParser 를 사용할 필요는 없습니다.
import { Generator, JSONParser } from 'mitumc'

const generator = new Generator('mitum')
const currencyGenerator = generator.currency

// ... omitted
// ... create operations
// ... refer to above `Make Your First Operation`
// ... suppose you have already made operations - createAccount, keyUpdater, transfer and a seal - seal

JSONParser.toJSONString(createAccount.dict()) // print operation createAccount in JSON
JSONParser.toJSONString(keyUpdater.dict()) // print operation keyUpdater in JSON
JSONParser.toJSONString(transfer.dict()) // print operation transfer in JSON
JSONParser.toJSONString(seal) // print seal seal in JSON

JSONParser.getFile(createAccount.dict(), 'createAccount.json'); // getFile(dict object, file path)
JSONParser.getFile(keyUpdater.dict(), 'keyUpdater.json');
JSONParser.getFile(transfer.dict(), 'transfer.json');
JSONParser.getFile(seal, 'seal.json');

Python

이 페이지는 Python으로 작성된 Mitum SDK에 관한 문서입니다.
자세한 내용은 mitum-py-util 을 참고해주세요.

Get Started

Prerequisite and Requirements
이 패키지는 다음 환경에서 개발되었습니다.
$ python --version
Python 3.9.2
Installation
  • git을 사용하면,

$ git clone https://github.com/ProtoconNet/mitum-py-util.git

$ cd mitum-py-util

$ python setup.py install
setup.py이 제대로 작동하지 않는다면, setup.py 실행 전 필요한 패키지를 requirements.txt를 사용하여 설치해주세요.
$ pip install -r requirements.txt

Make Your First Operation

이 예제는 mitum-py-utilcreate-account operation을 생성하는 방법에 대해 설명합니다.
key-updatertransfer operation 생성 방법은 Support Operations 에서 확인하세요.
Get Available Account
시작하기 전에, 네트워크에 등록된 계정을 가지고 있어야 합니다.
Mitum Currency에서는 오직 이미 존재하는 계정만이 블록에 저장될 수 있는 새로운 operation을 만들 수 있습니다.
계정은 다음과 같은 요소들로 이루어져있습니다.
1. pairs of (public key, weight); aka `keys`
- public key has suffix `mpu`
- The range of each weight should be in 1 <= weight <= 100
- If an account have single public key, the account is called 'single-sig account', or it's called 'multi-sig account'

1. threshold
- The range of threshold should be in 1 <= threshold <= 100
- The sum of all weights of the account should be over or equal to threshold
아직 아무 계정도 가지고 있지 않다면 다른 계정에 당신의 첫 계정을 만들어 달라 요청해야 합니다.
Get Mitum Keypair 파트에서 계정을 위한 키페어를 생성할 수 있습니다.
(public key, weight)쌍과 threshold를 새 계정 생성을 도와줄 계정 보유자에게 전달하세요.
서명을 위해 계정의 각 공개키에 상응하는 개인키를 기억하고 있어야 합니다. 다른 사람에게 개인키를 알려주지 마세요!
물론 계정 주소 또한 sender 로 사용해야 하기 때문에 기억하고 있어야 합니다.
등록되지 않은 계정으로도 operation을 생성할 수는 있지만 해당 operation들은 브로드캐스팅 이후 처리 거부될 것입니다.
이제 첫 operation을 만들기 위해 다음 장으로 이동하세요.
Create Generator
operation의 대부분의 요소는 Generator 로 생성합니다.
Mitum Currency에 대해서는 Generator.currency 를 사용하세요.
Generator 를 선언할 때, network id 가 필요합니다.
network id 는 네트워크에 따라 다릅니다.
이 페이지에서는 mitum 을 네트워크 id로 가정합니다.
from mitumc import Generator

generator = Generator('mitum')
currencyGenerator = generator.currency
Generator 에 대한 더 자세한 내용은 Major Classes 로 이동하여 Generator를 참고하세요.
또한, 네트워크 상에서 사용할 수 있는 등록된 계정을 가지고 있어야 합니다.
이제 새로운 operation을 만들기 위한 준비가 끝났습니다.
Create Operation Item
operation이 실행해야할 모든 것은 operation이 아닌 operation fact에 들어있습니다.
fact는 sender, token 등의 기본적인 정보를 담고 있습니다.
사실, 실제 operation의 지시 사항은 그 중에서도 Item에 들어있습니다.
한 마디로, operation을 위해 item들을 먼저 생성해야 한다는 뜻입니다.
아래 조건에 따라 계정을 생성하려 하는 상황이라고 가정해봅시다.
1. The keys and threshold of the account will be,
    - keys(public key, weight): (kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu, 50), (pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu, 50)
    - threshold: 100

2. The initial balance of the account will be,
    - balance(currency id, amount): (MCC, 10000), (PEN, 20000)
계정이 가지고 있는 키의 수가 2 개이기 때문에, 새로운 계정은 multi-sig 계정이 될 것입니다.
새 계정에 대한 모든 조건이 결정되었으면 아래와 같이 item을 생성하세요.
key1 = currencyGenerator.key("kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu", 50) # key(public key, weight)
key2 = currencyGenerator.key("pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu", 50)
keys = currencyGenerator.keys([key1, key2], 100) # keys(keyList, threshold)

amount1 = currencyGenerator.amount('MCC', 10000) # amount(currency id, amount)
amount1 = currencyGenerator.amount('PEN', 20000)
amounts = currencyGenerator.amounts([amount]) # amounts(amountList)

createAccountsItem = currencyGenerator.getCreateAccountsItem(keys, amounts)
  • 우선, Generator.currency.key(public key, weight) 를 사용해 각 key를 생성합니다..

  • 다음으로 모든 키와 계정 threshold를 Generator.currency.keys(key list, threshold) 로 결합합니다.

  • 그리고, Generator.currency.amount(currencyId, amount) 를 사용해 각 amount를 생성합니다..

  • 다음 Generator.currency.amounts(amount list) 로 모든 amount를 결합합니다.

  • 마지막으로, Generator.currency.getCreateAccountsItem(keys, amounts) 를 사용해 item을 생성하세요.

물론 각 item의 내용을 다음 조건 하에서 사용자화 할 수 있습니다.
- `keys`를 사용하여 생성하는 `Keys`는 key를 10개까지 포함할 수 있습니다.
- item 당 최대 10개의 amount를 가질 수 있기 때문에 `amounts`의 amount list에는 amount를 10개까지 넣을 수 있습니다.
- 게다가, `fact`는 item을 여러 개 포함할 수 있습니다. fact 당 item 개수는 최대 10 개입니다.
Create Operation Fact
fact 는 반드시 items, sender, token, fact hash 를 가져야 합니다.
tokenfact hash 는 SDK가 자동적으로 생성해주므로 걱정하지 않아도 됩니다.
반드시 제공해야할 정보는 itemssender 에 대한 것입니다.
item을 생성하는 방법은 바로 위에서 설명하였습니다.
아래 조건을 만족할 수 있는 계정만 sender 로 사용할 수 있다는 것을 명심하세요.
1. 이미 생성되어 등록된 계정.
2. item의 각 amount에 대해 충분한 잔액을 보유한 계정.
3. 계정의 공개키에 상응하는 개인키(멀티 시그 계정인 경우 모든 개인키들 중 일부)를 알고 있는 계정.
그리고 다음과 같이 fact를 생성하세요!
senderAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca" # sender's account address; replace with your address
createAccountsFact = currencyGenerator.getCreateAccountsFact(senderAddress, [createAccountsItem]) # getCreateAccountsFact(sender's address, item list)
만약 다수의 item을 가진 fact를 생성하고 싶다면 Generator.currency.getCreateAccountsFact(sender's address, item list) 의 item list에 item을 모두 넣으세요.
Create Operation
드디어 operation을 생성하기 위한 단계에 도달하였습니다!
준비해야 하는 것은 오직 sender의 개인키입니다. 개인키는 fact에 서명하기 위해 필요합니다.
개인키의 서명은 fact 서명으로서 fact_signs 에 추가됩니다.
fact_signs 의 모든 signer의 weight들의 총합이 sender 의 threshold 이상이어야 합니다.
fact_sign에는 오직 sender 의 개인키의 서명만이 유효합니다.
operation에는 memo 값이 존재하지만 필수적이지는 않습니다. 필요한 내용을 넣어도 괜찮지만 memo 또한 operation hash 값에 영향을 미치기 때문에 주의해야 합니다.
이 예제에서는 sender 가 single-sig 계정이라고 가정합니다. 즉, sender의 계정에는 오직 하나의 키 밖에 없습니다.
만약 sender 가 multi-sig 계정이라면 fact_signs 에 여러 개의 서명을 추가해야 할 수 있습니다.
어떤 키들이 반드시 서명해야 하는지는 계정의 threshold와 각 key의 weight에 달렸습니다.
senderPrivateKey = "KxD8T82nfwsUmQu3iMXENm93YTTatGFp1AYDPqTo5e6ycvY1xNXpmpr" # sender's private key; replace with your private key

createAccounts = generator.getOperation(createAccountsFact, "") # getOperation(fact, memo)
createAccounts.addFactSign(senderPrivateKey); # addFactSign(private key) add fact signature to fact_signs
operation을 생성하기 위해 Generator.currency.getOperation(fact, memo) 가 아닌 Generator.getOperation(fact, memo) 을 사용해야 한다는 점에 주의하세요.
아쉽지만 하나의 operation에는 하나의 fact만 넣을 수 있습니다.
Create Seal
사실 operation 자체로도 계정을 생성하는 데는 충분합니다.
하지만 종종 여러 개의 operation을 seal로 감싸 전송해야 할 일이 있을 수 있습니다. - 여러 개의 각각 다른 계정으로부터 하나의 계정으로 동시에 송금하는 경우 등
위에 언급한대로 하나의 seal은 여러 개의 operation을 가질 수 있습니다.
seal에 넣을 수 있는 operation의 최대 개수는 노드 정책에 따라 다를 수 있습니다.
따라서 seal을 생성하기 전 하나의 seal에 몇 개의 operation을 넣을 수 있는지 확인해야 합니다.
어쨌든 mitum-py-util을 사용해 seal을 생성하는 것은 간단합니다.
준비해야 하는 것은 Mitum 키 패키지로부터 얻은 아무 개인키입니다.
mpr 타입 접미사가 붙은 어떤 btc compressed wif 형식 키라도 가능합니다.
signKey = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"

operations = [createAccounts]
seal = generator.getSeal(signKey, operations)
getOperation 의 경우와 같이, 단순히 Generator.getSeal(signer, operation list) 를 사용하세요.
감싸길 원하는 모든 operation을 operation list에 추가하세요.

Support Operations

이 파트에서는 각 operation에 대한 코드 예제를 제공합니다.
mitum-py-util가 지원하는 각 Mitum 모델의 operation은 다음과 같습니다.

Model

Support Operations

Currency

create account, key updater, transfer

Currency Extension

create contract account, withdraw

Document

create document, update document, (sign document)

Feefi

pool register, pool policy updater, pool deposit, pool withdraw

NFT

collection register, collection policy updater, mint, transfer, burn, sign, approve, delegate

Currency
Create Account
create-account 의 예제는 이미 설명했으나 여기서 하나의 코드 블록으로 다시 한 번 소개합니다.
새 계정을 생성하기 위해 다음과 같은 것을 준비해야 합니다.
  • 새로운 계정의 정보: (public key, weight)쌍과 threshold로 이루어진 계정 keys, (currency id, amount) 쌍으로 이루어진 계정 초기 잔액

  • 이미 존재하는 sender의 계정 - 특히 계정 주소와 개인키를 알아야 합니다.

이전에 설명한대로 어떤 개인키가 서명해야 하는지는 threshold와 weight들의 구성에 달렸습니다.
from mitumc import Generator

senderPrivateKey = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"
senderAddress = "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca"

generator = Generator('mitum')
gn = generator.currency

key = gn.key("2177RF13ZZXpdE1wf7wu5f9CHKaA2zSyLW5dk18ExyJ84mpu", 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)
자세한 설명은 생략합니다. Make Your First Operation 의 시작 부분을 확인하세요.
Key Updater
이 operation은 말 그대로 계정의 키를 업데이트하기 위한 것입니다.
예를 들어, 다음과 같이 키를 업데이트할 수 있습니다.
- I have an single sig account with keys: (kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu, 100), threshold: 100
- But I want to replace keys of the account with keys: (22ndFZw57ax28ydC3ZxzLJMNX9oMSqAfgauyWhC17pxDpmpu, 50), (22wD5RWsRFAr8mHkYmmyUDzKf6VBNgjHcgc3YhKxCvrZDmpu, 50), threshold: 100
- Then you can use key-updater operation to reach the goal!
single-sig 계정을 multi-sig로 바꾸거나 반대로 multi-sig에서 single-sig로 바꿀 수 있을까요?
물론 가능합니다!
계정 키를 업데이트하기 위해서 다음과 같은 것을 준비해야 합니다.
  • 키를 교체하고자 하는 계정(target)의 정보 - 계정 주소와 개인키; 어떤 개인키가 필요한지는 threshold와 키 weight들에 따라 다를 수 있습니다.

  • 새로운 keys: (public key, weights)쌍들과 threshold

  • 수수료를 지불하려는 currency의 충분한 잔액

create-accounttransferitem operation 생성을 위해 item을 만들어야 하지만 key-updater 는 item이 필요하지 않습니다.
바로 fact를 만드세요.
from mitumc import Generator

targetPrivateKey = "KzejtzpPZFdLUXo2hHouamwLoYoPtoffKo5zwoJXsBakKzSvTdbzmpr"
targetAddress = "JDhSSB3CpRjwM8aF2XX23nTpauv9fLhxTjWsQRm9cJ7umca"

generator = Generator('mitum')
gn = generator.currency

key1 = gn.key("22ndFZw57ax28ydC3ZxzLJMNX9oMSqAfgauyWhC17pxDpmpu", 50)
key2 = gn.key("22wD5RWsRFAr8mHkYmmyUDzKf6VBNgjHcgc3YhKxCvrZDmpu", 50)
keys = gn.keys([key1, key2], 100)

keyUpdaterFact = gn.getKeyUpdaterFact(targetAddress, keys, "MCC") # getKeyUpdaterFact(target address, new keys, currency id for fee)

keyUpdater = generator.getOperation(keyUpdaterFact, "")
keyUpdater.addFactSign(targetPrivateKey)
  • 계정의 키를 업데이트한 후에는 이전의 키를 사용할 수 없게 됩니다. 계정의 새로운 키페어의 개인키로 서명해야 합니다.

  • 따라서 네트워크에 key-updater operation을 전송하기 전, 새로운 키들을 기록해두세요.

Transfer
드디어 다른 계정으로 토큰을 송금할 수 있습니다!
다른 operation들과 같이, 다음과 같은 것들을 준비해야 합니다.
  • sender의 계정 정보 - 계정 주소와 개인키

  • 송금할 (currency id, amount) 쌍

create-account 처럼 fact 생성 전 item을 먼저 만들어야 합니다.
operation을 전송하기 전 전송하려는 토큰의 잔액이 충분한지 먼저 확인하세요.
시작하기 전, 다음과 같이 토큰을 전송하려 한다고 가정해 봅시다.
  • 1000000 MCC token

  • 15000 PEN token

그리고 receiver는,
  • CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca

최대 10 (currency id, amount) 쌍이 item 하나에 들어갈 수 있습니다.
또한 최대 10개의 item이 한 fact에 들어갈 수 있습니다. 하지만 각 item의 receiver는 달라야 합니다.
from mitumc import Generator

generator = Generator('mitum')
gn = generator.currency

senderPrivateKey = "KzdeJMr8e2fbquuZwr9SEd9e1ZWGmZEj96NuAwHnz7jnfJ7FqHQBmpr"
senderAddress = "2D5vAb2X3Rs6ZKPjVsK6UHcnGxGfUuXDR1ED1hcvUHqsmca"
receiverAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca"

amount = gn.amount('MCC', 1000000)
amount = gn.amount('PEN', 15000)
amounts = gn.amounts([amount1, amount2])

transfersItem = gn.getTransfersItem(receiverAddress, amounts) # getTransfersItem(receiver address, amounts)
transfersFact = gn.getTransfersFact(senderAddress, [transfersItem]) # getTransfersFact(sender addrewss, item list)

transfers = generator.getOperation(transfersFact, "")
transfers.addFactSign(senderPrivateKey)
Currency Extension
Create Contract Account
이 operation을 전송하여 컨트랙트 계정을 생성할 수 있습니다.
create-contract-account operation을 생성하는 과정은 create-account과 동일합니다.
컨트랙트 계정과 일반 계정의 차이점은 컨트랙트 계정의 경우 계정 정보에 공개키가 포함되지 않는다는 점입니다.
따라서 컨트랙트 계정은 operation의 전송자로서 operation을 전송하거나 시작할 수 없습니다.
컨트랙트 계정으로 전송된 토큰들은 오직 컨트랙트 계정의 소유자만이 다시 인출할 수 있습니다.
다음은 create-contract-account operation을 생성하는 예이며, 자세한 설명은 생략되었습니다.
from mitumc import Generator

senderPrivateKey = "L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr"
senderAddress = "5fbQg8K856KfvzPiGhzmBMb6WaL5AsugUnfutgmWECPbmca"

generator = Generator('mitum')
gn = generator.currency

key = gn.key("2177RF13ZZXpdE1wf7wu5f9CHKaA2zSyLW5dk18ExyJ84mpu", 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)
Withdraw
컨트랙트 계정의 소유자는 withdraw operation을 통해 컨트랙트 계정으로부터 토큰을 인출할 수 있습니다.
from mitumc import Generator

generator = Generator('mitum')
gn = generator.currency

senderPrivateKey = "KzdeJMr8e2fbquuZwr9SEd9e1ZWGmZEj96NuAwHnz7jnfJ7FqHQBmpr"
senderAddress = "2D5vAb2X3Rs6ZKPjVsK6UHcnGxGfUuXDR1ED1hcvUHqsmca"
targetAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca"

amount = gn.amount('MCC', 1000000)
amount = gn.amount('PEN', 15000)
amounts = gn.amounts([amount1, amount2])

withdrawsItem = gn.extension.getWithdrawsItem(targetAddress, amounts)
withdrawsFact = gn.extension.getWithdrawsFact(senderAddress, [withdrawsItem])

withdraws = generator.getOperation(withdrawsFact, "")
withdraws.addFactSign(senderPrivateKey)
document, feefi, NFT 모델의 operation을 생성하는 방법은 README 에서 확인할 수 있습니다.

Sign

operation이 정상적으로 블록에 저장되기 위해서는 operation의 서명들이 특정 조건을 만족해야 합니다.
주의해야할 점은,
  • 모든 서명이 계정의 개인키의 서명인가요?

  • 각 signer의 weight들을 모두 합한 값이 계정의 threshold 이상인가요?

물론, 각 operation이 지켜야 할 다른 조건들이 더 있습니다. 하지만 여기서는 (fact)서명에만 집중하겠습니다.
각 키의 weight가 30이고 threshold가 50인 멀티 시그 계정이 있다고 가정해봅시다.
즉, 다음과 같습니다.
  • (pub1, 30)

  • (pub2, 30)

  • (pub3, 30)

  • threshold: 50

이 계정이 operation을 전송하길 원할 때, operation은 서로 다른 signer의 최소 2 개의 fact 서명을 가지고 있어야 합니다.
  1. CASE1: fact signatures signed by pub1’s private key and pub2’s private key

    1. the sum of pub1’s weight and pub2’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  2. CASE2: fact signatures signed by pub2’s private key and pub3’s private key

    1. the sum of pub2’s weight and pub3’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  3. CASE3: fact signatures signed by pub1’s private key and pub3’s private key

    1. the sum of pub1’s weight and pub3’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  4. CASE4: fact signatures signed by pub1’s private key, pub2’s private key, pub3’s private key

    1. the sum of pub1’s weight, pub2’s weight and pub3’s weight: 90

    2. the sum of weights = 90 > threshold = 50

    3. So the operation with these two fact signatures is available

그러므로 조건을 만족하기 위해 각 operation에 여러 개의 signature를 추가해야 합니다. (Operation.addFactSign(private key) 를 사용하세요.)
CASE4의 경우와 같이 weight들의 총합 >= threshold 조건이 지켜지는 한 모든 개인키로 서명하는 것도 가능합니다.
Add Fact Sign to Operation
operation 생성 시 fact 서명을 추가하는 방법 외에 fact 서명을 추가하는 다른 방법이 하나 더 있습니다.
operation에 새 서명을 추가하기 위해 준비해야 할 것은 다음과 같습니다.
  • 서명할 개인키 - 이 개인키는 계정의 키여야 합니다.

  • python dictionary 객체 혹은 외부 JSON 파일 형태의 operation

  • Network ID

우선 Generator 처럼 network id 와 함께 Signer 를 생성합니다.
from mitumc import Signer

networkId = 'mitum'
signKey = 'L1V19fBjhnxNyfuXLWw6Y5mjFSixzdsZP4obkXEERskGQNwSgdm1mpr'
signer = Signer(networkId, signKey)
그리고, 서명하세요!
signed = signer.signOperation('operation.json') # signOperation(filePath)
아웃풋인 signed는 mitum-js-util의 Operation 객체가 아닙니다. 단지 dictionary 객체입니다.
한 번에 여러 개의 서명을 추가하길 원한다면 signed - dictionary object에 다른 개인키로 Signer를 다시 만들어 서명해야 합니다.

Details

Get Mitum Keypair
Mitum 키페어 생성 방법을 소개합니다!
시작 전, 중요한 것을 설명하겠습니다.
Mitum의 계정의 주소, 개인키, 공개키는 각자 특별한 타입 접미사를 가지고 있습니다. 그것은 다음과 같습니다.
  • Account Address: mca

  • Private Key: mpr

  • Public Key: mpu

예를 들어, 한 single sign 계정은 다음과 같은 형태를 가집니다.
  • Account Address: 9XyYKpjad2MSPxR4wfQHvdWrZnk9f5s2zc9Rkdy2KT1gmca

  • Private Key: L11mKUECzKouwvXwh3eyECsCnvQx5REureuujGBjRuYXbMswFkMxmpr

  • Public Key: 28Hhy6jwkEHx75bNLmG66RQu1LWiZ1vodwRTURtBJhtPWmpu

키페어를 생성하는 세 가지 방법이 있습니다.
Just Create New Keypair
mitum-py-util가 무작위의 키페어를 생성해줍니다.
getNewKeypair() 를 사용하세요.
from mitumc.key import getNewKeypair

# get new Keypair
kp = getNewKeypair() # returns BTCKeyPair
kp.privateKey # KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr
kp.publicKey # 24TbbrNYVngpPEdq6Zc5rD1PQSTGQpqwabB9nVmmonXjqmpu
Get Keypair From Your Private Key
이미 개인키를 가지고 있다면 해당 키로부터 키페어를 생성할 수 있습니다.
from mitumc.key import getKeypairFromPrivateKey

# get Keypair from your private key
pkp = getKeypairFromPrivateKey("L2ddEkdgYVBkhtdN8HVXLZk5eAcdqXxecd17FDTobVeFfZNPk2ZDmpr")
Get Keypair From Your Seed
시드로부터 키페어를 생성할 수도 있습니다. 키페어의 개인키를 기억하지 못하더라도 시드를 통해 복구할 수 있습니다.
문자열 시드 길이는 36 이상이어야 합니다.
from mitumc.key import getKeypairFromSeed

# get Keypair from your seed
skp = getKeypairFromSeed("Thisisaseedforthisexample.len(seed)>=36.")
Get Account Address with Keys
계정 주소를 threshold와 계정의 모든 (public key, weight)쌍을 사용해 알아낼 수 있습니다.
하지만 이 방법은 계정의 threshold나 키가 업데이트 되지 않은 경우에만 사용할 수 있습니다.
예제의 계정 정보는 다음과 같습니다.
  • key1: (vmk1iprMrs8V1NkA9DsSL3XQNnUW9SmFL5RCVJC24oFYmpu, 40)

  • key2: (29BQ8gcVfJd5hPZCKj335WSe4cyDe7TGrjam7fTrkYNunmpu, 30)

  • key3: (uJKiGLBeXF3BdaDMzKSqJ4g7L5kAukJJtW3uuMaP1NLumpu, 30)

  • threshold: 100

from mitumc import Generator

gn = Generator('mitum').currency

pub1 = "vmk1iprMrs8V1NkA9DsSL3XQNnUW9SmFL5RCVJC24oFYmpu"
pub2 = "29BQ8gcVfJd5hPZCKj335WSe4cyDe7TGrjam7fTrkYNunmpu"
pub3 = "uJKiGLBeXF3BdaDMzKSqJ4g7L5kAukJJtW3uuMaP1NLumpu"

key1 = gn.key(pub1, 40)
key2 = gn.key(pub2, 30)
key3 = gn.key(pub3, 30)

keys = gn.keys([key1, key2, key3], 100)
address = keys.address # your address
Major Classes
Generator
Generator 는 Mitum Currency operation 생성을 도와줍니다.
Generator 를 사용하기 전 network id 를 설정해야 합니다.
  • Mitum Currency: Generator.currency

  • Mitum Currency Extension: Generator.currency.extension

  • Mitum Document: Generator.document

  • Mitum Feefi: Generator.feefi

  • Mitum NFT: Generator.nft

from mitumc import Generator

generator = Generator('mitum')
currencyGenerator = generator.currency
extensionGenerator = generator.currency.extension
documentGenerator = generator.document
feefiGenerator = generator.feefi
nftGenerator = generator.nft
Generator 가 제공하는 모든 메서드는 다음과 같습니다.
# For Mitum Currency
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)

# For Mitum Currency Extension
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
Generator.document.getCreateDocumentsItem(document, currencyId)
Generator.document.getUpdateDocumentsItem(document, currencyId)
Generator.document.getCreateDocumentsFact(sender, items)
Generator.document.getUpdateDocumentsFact(sender, items)

# For 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)

# For 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
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
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)

# Common
Generator.getOperation(fact, memo)
Generator.getSeal(signKey, operations)
Signer
Signer 는 이미 생성된 operation에 새로운 fact 서명을 추가할 때 사용합니다.
Generator 와 같이 network id 가 설정되어야 합니다.
서명에 사용할 개인키도 준비해야 합니다.
Signer 는 오직 하나의 메서드를 제공합니다.
Signer.signOperation(operation)
Signer 의 정확한 사용 방법은 ‘Make Your First Operation - Sign’로 돌아가서 확인하세요.
JSONParser
이 클래스는 편의를 위해 개발되었습니다.
Operation 을 내보내거나 JSON 형식으로 출력하기 위해 다른 패키지를 사용하길 원한다면 굳이 mitum-py-util의 JSONParser 를 사용할 필요는 없습니다.
from mitumc import JSONParser

# ... omitted
# ... create operations
# ... refer to above `Make Your First Operation`
# ... suppose you have already made operations - createAccount, keyUpdater, transfer and a seal - seal

JSONParser.toString(createAccount.dict()) # print operation createAccount in JSON
JSONParser.toString(keyUpdater.dict()) # print operation keyUpdater in JSON
JSONParser.toString(transfer.dict()) # print operation transfer in JSON
JSONParser.toString(seal) # print seal seal in JSON

JSONParser.toFile(createAccount.dict(), 'createAccount.json') # toFile(dict object, file path)
JSONParser.toFile(keyUpdater.dict(), 'keyUpdater.json')
JSONParser.toFile(transfer.dict(), 'transfer.json')
JSONParser.toFile(seal, 'seal.json')

Java

이 페이지는 Java로 작성된 SDK에 관한 문서입니다.
자세한 내용은 mitum-java-util 을 참고해주세요.

Get Started

Prerequisite and Requirements
이 패키지는 다음 환경에서 개발되었습니다.
$ java -version
java 17.0.1 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing)

$ javac -version
javac 17.0.1
Installation
레포지토리에서 Download 하세요.
현재 최신 버전은 mitum-java-util-4.1.1-jdk17.jar 입니다.
Gradle 을 사용하세요.
implementation files('./lib/mitum-java-util-4.1.1-jdk17.jar')

Make Your First Operation

이 예제는 mitum-java-utilcreate-account operation을 생성하는 방법에 대해 설명합니다.
key-updatertransfer operation 생성 방법은 Support Operations 에서 확인하세요.
Get Available Account
시작하기 전에, 네트워크에 등록된 계정을 가지고 있어야 합니다.
Mitum에서는 오직 이미 존재하는 계정만이 블록에 저장될 수 있는 새로운 operation을 만들 수 있습니다.
계정은 다음과 같은 요소들로 이루어져있습니다.
1. pairs of (public key, weight); aka `keys`
- public key has suffix `mpu`
- The range of each weight should be in 1 <= weight <= 100
- If an account have single public key, the account is called 'single-sig account', or it's called 'multi-sig account'

1. threshold
- The range of threshold should be in 1 <= threshold <= 100
- The sum of all weights of the account should be over or equal to threshold
아직 아무 계정도 가지고 있지 않다면 다른 계정에 당신의 첫 계정을 만들어 달라 요청해야 합니다.
Get Mitum Keypair 파트에서 계정을 위한 키페어를 생성할 수 있습니다.
(public key, weight)쌍과 threshold를 새 계정 생성을 도와줄 계정 보유자에게 전달하세요.
서명을 위해 계정의 각 공개키에 상응하는 개인키를 기억하고 있어야 합니다. 다른 사람에게 개인키를 알려주지 마세요!
물론 계정 주소 또한 sender 로 사용해야 하기 때문에 기억하고 있어야 합니다.
등록되지 않은 계정으로도 operation을 생성할 수는 있지만 해당 operation들은 브로드캐스팅 이후 처리 거부될 것입니다.
이제 첫 operation을 만들기 위해 다음 장으로 이동하세요.
Create Generator
operation의 대부분의 요소는 Generator 로 생성합니다.
Mitum Currency에 대해서는 Generator.currency 를 사용하세요.
Generator 를 선언할 때, network id 가 필요합니다.
network id 는 네트워크에 따라 다릅니다.
이 페이지에서는 mitum 을 네트워크 id로 가정합니다.
/*
import org.mitumc.sdk.Generator
*/
String id = "mitum";
Generator generator = Generator.get(id);
Generator 에 대한 더 자세한 내용은 Major Classes 로 이동하여 Generator를 참고하세요.
또한, 네트워크 상에서 사용할 수 있는 등록된 계정을 가지고 있어야 합니다.
이제 새로운 operation을 만들기 위한 준비가 끝났습니다.
Create Operation Item
operation이 실행해야할 모든 것은 operation이 아닌 operation fact에 들어있습니다.
fact는 sender, token 등의 기본적인 정보를 담고 있습니다.
사실, 실제 operation의 지시 사항은 그 중에서도 Item에 들어있습니다.
한 마디로, operation을 위해 item들을 먼저 생성해야 한다는 뜻입니다.
아래 조건에 따라 계정을 생성하려 하는 상황이라고 가정해봅시다.
1. The keys and threshold of the account will be,
    - keys(public key, weight): (kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu, 50), (pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu, 50)
    - threshold: 100

2. The initial balance of the account will be,
    - balance(currency id, amount): (MCC, 10000), (PEN, 20000)
계정이 가지고 있는 키의 수가 2개이기 때문에, 새로운 계정은 multi-sig 계정이 될 것입니다.
새 계정에 대한 모든 조건이 결정되었으면 아래와 같이 item을 생성하세요.
/*
import org.mitumc.sdk.key.*;
import org.mitumc.sdk.operation.Amount;
import org.mitumc.sdk.operation.currency.*;
*/
Key key1 = Key.get("kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu", 50);
Key key2 = Key.get("pWoFhRP3C7ocebSRPxTPfeaJZpnyKpEkxQqi6fAD4SHompu", 50);
Keys keys = Keys.get(new Key[]{ key1, key2 }, 100);

Amount amount1 = Amount.get("MCC", "10000");
Amount amount2 = Amount.get("PEN", "20000");

CreateAccountsItem item = generator.currency.getCreateAccountsItem(keys, new Amount[]{ amount1, amount2 }); // newCreateAccountsItem(keys, amount list)
  • 우선, Key.get(public key, weight) 를 사용해 각 key를 생성합니다.

  • 다음으로 모든 키와 계정 threshold를 Keys.get(key list, threshold) 로 결합합니다.

  • 그리고, Amount.get(currencyId, amount) 를 사용해 각 amount를 생성합니다.

  • 마지막으로, Generator.currency.getCreateAccountsItem(keys, amount list) 를 사용해 item을 생성하세요.

물론 각 item의 내용을 다음 조건 하에서 사용자화 할 수 있습니다.
- `keys`를 사용하여 생성하는 `Keys`는 key를 10개까지 포함할 수 있습니다.
- 각 amount가 `amounts`로 생성된 `Amount list`는 item 당 amount를 10개까지 포함할 수 있습니다.
- 게다가, `fact`는 item을 여러 개 포함할 수 있습니다. fact 당 item 개수는 최대 10 개입니다.
Create Operation Fact
fact 는 반드시 items, sender, token, fact hash 를 가져야 합니다.
tokenfact hash 는 SDK가 자동적으로 생성해주므로 걱정하지 않아도 됩니다.
반드시 제공해야할 정보는 itemssender 에 대한 것입니다.
item을 생성하는 방법은 바로 위에서 설명하였습니다.
아래 조건을 만족할 수 있는 계정만 sender 로 사용할 수 있다는 것을 명심하세요.
1. 이미 생성되어 등록된 계정.
2. item의 각 amount에 대해 충분한 잔액을 보유한 계정.
3. 계정의 공개키에 상응하는 개인키(멀티 시그 계정인 경우 모든 개인키들 중 일부)를 알고 있는 계정.
그리고 다음과 같이 fact를 생성하세요!
/*
import org.mitumc.sdk.operation.currency.*;
*/
String senderAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca"; // sender's account address; replace with your address
CreateAccountsFact fact = generator.currency.getCreateAccountsFact(senderAddress, new CreateAccountsItem[]{ item });  // newCreateAccountsFact(sender address, item list)
만약 다수의 item을 가진 fact를 생성하고 싶다면 Generator.currency.getCreateAccountsFact(sender's address, item list) 의 item list에 item을 모두 넣으세요.
Create Operation
드디어 operation을 생성하기 위한 단계에 도달하였습니다!
준비해야 하는 것은 오직 sender의 개인키입니다. 개인키는 fact에 서명하기 위해 필요합니다.
개인키의 서명은 fact 서명으로서 fact_signs 에 추가됩니다.
fact_signs 의 모든 signer의 weight들의 총합이 sender 의 threshold 이상이어야 합니다.
fact_sign에는 오직 sender 의 개인키의 서명만이 유효합니다.
operation에는 memo 값이 존재하지만 필수적이지는 않습니다. 필요한 내용을 넣어도 괜찮지만 memo 또한 operation hash 값에 영향을 미치기 때문에 주의해야 합니다.
이 예제에서는 sender 가 single-sig 계정이라고 가정합니다. 즉, sender의 계정에는 오직 하나의 키 밖에 없습니다.
만약 sender 가 multi-sig 계정이라면 fact_signs 에 여러 개의 서명을 추가해야 할 수 있습니다.
어떤 키들이 반드시 서명해야 하는지는 계정의 threshold와 각 key의 weight에 달렸습니다.
/*
import org.mitumc.sdk.operation.Operation;
*/
String senderPrivateKey = "KxD8T82nfwsUmQu3iMXENm93YTTatGFp1AYDPqTo5e6ycvY1xNXpmpr";

Operation operation = generator.getOperation(fact);
operation.sign(senderPrivateKey);
operation을 생성하기 위해 Generator.currency.getOperation(fact, memo) 가 아닌 Generator.getOperation(fact, memo) 을 사용해야 한다는 점에 주의하세요.
아쉽지만 하나의 operation에는 하나의 fact만 넣을 수 있습니다.
Create Seal
사실 operation 자체로도 계정을 생성하는 데는 충분합니다.
하지만 종종 여러 개의 operation을 seal로 감싸 전송해야 할 일이 있을 수 있습니다. - 여러 개의 각각 다른 계정으로부터 하나의 계정으로 동시에 송금하는 경우 등
위에 언급한대로 하나의 seal은 여러 개의 operation을 가질 수 있습니다.
seal에 넣을 수 있는 operation의 최대 개수는 노드 정책에 따라 다를 수 있습니다.
따라서 seal을 생성하기 전 하나의 seal에 몇 개의 operation을 넣을 수 있는지 확인해야 합니다.
어쨌든 mitum-java-util을 사용해 seal을 생성하는 것은 간단합니다.
준비해야 하는 것은 Mitum 키 패키지로부터 얻은 아무 개인키입니다.
mpr 타입 접미사가 붙은 어떤 btc compressed wif 형식 키라도 가능합니다.
String signKey = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
HashMap<String, Object> seal = gn.getSeal(signKey, new Operation[]{ operation }); // getSeal(sign key, operation list)
getOperation 의 경우와 같이, 단순히 Generator.getSeal(signer, operation list) 를 사용하세요.
감싸길 원하는 모든 operation을 operation list에 추가하세요.

Support Operations

이 파트에서는 각 operation에 대한 코드 예제를 제공합니다.
mitum-java-util가 지원하는 각 Mitum 모델의 operation은 다음과 같습니다.

Model

Support Operations

Currency

create account, key updater, transfer

Currency Extension

create contract account, withdraw

Document

create document, update document, (sign document)

Feefi

pool register, pool policy updater, pool deposit, pool withdraw

NFT

collection register, collection policy updater, mint, transfer, burn, sign, approve, delegate

Currency
Create Account
create-account 의 예제는 이미 설명했으나 여기서 하나의 코드 블록으로 다시 한 번 소개합니다.
새 계정을 생성하기 위해 다음과 같은 것을 준비해야 합니다.
  • 새로운 계정의 정보: (public key, weight)쌍과 threshold로 이루어진 계정 keys, (currency id, amount) 쌍으로 이루어진 계정 초기 잔액

  • 이미 존재하는 sender의 계정 - 특히 계정 주소와 개인키를 알아야 합니다.

이전에 설명한대로 어떤 개인키가 서명해야 하는지는 threshold와 weight들의 구성에 달렸습니다.
/*
import org.mitumc.sdk.key.*;
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
*/

String senderPrivateKey = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
String senderAddress = "FcLfoPNCYjSMnxLPiQJQFGTV15ecHn3xY4J2HNCrqbCfmca";

Generator gn = Generator.get("mitum"); // network id: mitum

Key key = Key.get("knW2wVXH399P9Xg8aVjAGuMkk3uTBZwcSpcy4aR3UjiAmpu", 100);
Keys keys = Keys.get(new Key[]{ key }, 100); // becomes single-sig account

Amount amount = Amount.get("MCC", "1000");
CreateAccountsItem item = gn.currency.getCreateAccountsItem(keys, new Amount[]{ amount });

CreateAccountsFact fact = gn.currency.getCreateAccountsFact(senderAddress, new CreateAccountsItem[]{ item });

Operation createAccount = gn.getOperation(fact);
createAccount.sign(senderPrivateKey);
자세한 설명은 생략합니다. Make Your First Operation 의 시작 부분을 확인하세요.
Key Updater
이 operation은 말 그대로 계정의 키를 업데이트 하기 위한 것입니다.
예를 들어, 다음과 같이 키를 업데이트할 수 있습니다.
- I have an single sig account with keys: (kpYjRwq6gQrjvzeqQ91MNiCcR9Beb9sD67SuhQ6frPGwmpu, 100), threshold: 100
- But I want to replace keys of the account with keys: (22ndFZw57ax28ydC3ZxzLJMNX9oMSqAfgauyWhC17pxDpmpu, 50), (22wD5RWsRFAr8mHkYmmyUDzKf6VBNgjHcgc3YhKxCvrZDmpu, 50), threshold: 100
- Then you can use key-updater operation to reach the goal!
single-sig 계정을 multi-sig로 바꾸거나 반대로 multi-sig에서 single-sig로 바꿀 수 있을까요?
물론 가능합니다!
계정 키를 업데이트하기 위해서 다음과 같은 것을 준비해야 합니다.
  • 키를 교체하고자 하는 계정(target)의 정보 - 계정 주소와 개인키; 어떤 개인키가 필요한지는 threshold와 키 weight들에 따라 다를 수 있습니다.

  • 새로운 keys: (public key, weights)쌍들과 threshold

  • 수수료를 지불하려는 currency의 충분한 잔액

create-accounttransferitem operation 생성을 위해 item을 만들어야 하지만 key-updater 는 item이 필요하지 않습니다.
바로 fact를 만드세요.
/*
import org.mitumc.sdk.key.*;
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
*/

Generator gn = Generator.get("mitum"); // network id: mitum

String targetPrivateKey = "KzejtzpPZFdLUXo2hHouamwLoYoPtoffKo5zwoJXsBakKzSvTdbzmpr";
String targetAddress = "JDhSSB3CpRjwM8aF2XX23nTpauv9fLhxTjWsQRm9cJ7umca";

Key key1 = Key.get("22ndFZw57ax28ydC3ZxzLJMNX9oMSqAfgauyWhC17pxDpmpu", 50);
Key key2 = Key.get("22wD5RWsRFAr8mHkYmmyUDzKf6VBNgjHcgc3YhKxCvrZDmpu", 50);
Keys newKeys = Keys.get(new Key[]{ key1, key2 }, 100);

KeyUpdaterFact fact = gn.currency.getKeyUpdaterFact(targetAddress, "MCC", newKeys);
Operation keyUpdater = gn.getOperation(fact);
keyUpdater.sign(targetPrivateKey);
  • 계정의 키를 업데이트한 후에는 이전의 키를 사용할 수 없게 됩니다. 계정의 새로운 키페어의 개인키로 서명해야 합니다.

  • 따라서 네트워크에 key-updater operation을 전송하기 전, 새로운 키들을 기록해두세요.

Transfer
드디어 다른 계정으로 토큰을 송금할 수 있습니다!
다른 operation들과 같이, 다음과 같은 것들을 준비해야 합니다.
  • sender의 계정 정보 - 계정 주소와 개인키

  • 송금할 (currency id, amount) 쌍

create-account 처럼 fact 생성 전 item을 먼저 만들어야 합니다.
operation을 전송하기 전 전송하려는 토큰의 잔액이 충분한지 먼저 확인하세요.
시작하기 전, 다음과 같이 토큰을 전송하려 한다고 가정해 봅시다.
  • 1000000 MCC token

  • 15000 PEN token

그리고 receiver는,
  • CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca

최대 10 (currency id, amount) 쌍이 item 하나에 들어갈 수 있습니다.
또한 최대 10개의 item이 한 fact에 들어갈 수 있습니다. 하지만 각 item의 receiver는 달라야 합니다.
/*
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
*/
Generator gn = Generator.get("mitum"); // network id: mitum

String senderPrivateKey = "KzdeJMr8e2fbquuZwr9SEd9e1ZWGmZEj96NuAwHnz7jnfJ7FqHQBmpr";
String senderAddress = "2D5vAb2X3Rs6ZKPjVsK6UHcnGxGfUuXDR1ED1hcvUHqsmca";
String receiverAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca";

Amount amount1 = Amount.get("MCC", "100000")
Amount amount2 = Amount.get("PEN", "15000")

TransfersItem item = gn.currency.getTransfersItem(receiverAddress, new Amount[]{ amount1, amount2 }); // getTransfersItem(receiver address, amount list)
TransfersFact fact = gn.currency.getTransfersFact(senderAddress, new TransfersItem[]{ item }); // getTransfersFact(sender address, item list)

Operation transfer = gn.getOperation(fact);
transfer.sign(senderPrivateKey); // suppose sender is single-sig
Currency Extension
Create Contract Account
이 operation을 전송하여 새로운 컨트랙트 계정을 생성할 수 있습니다.
create-contract-account operation을 생성하기 위한 과정은 create-account와 동일합니다.
컨트랙트 계정과 일반 계정의 차이점은 컨트랙트 계정의 경우 계정 정보에 공개키가 포함되지 않는다는 점입니다.
따라서 컨트랙트 계정은 operation 전송자로서 스스로 operation을 전송하거나 시작할 수 없습니다.
컨트랙트 계정으로 전송된 토큰은 오직 컨트랙트 계정의 소유자만 인출 가능합니다.
다음은 create-contract-account operation을 생성하는 예제이며, 자세한 설명은 생략되었습니다.
/*
import org.mitumc.sdk.key.*;
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
import org.mitumc.sdk.operation.currency.extension.*;
*/

String senderPrivateKey = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
String senderAddress = "FcLfoPNCYjSMnxLPiQJQFGTV15ecHn3xY4J2HNCrqbCfmca";

Generator gn = Generator.get("mitum"); // network id: mitum

Key key = Key.get("knW2wVXH399P9Xg8aVjAGuMkk3uTBZwcSpcy4aR3UjiAmpu", 100);
Keys keys = Keys.get(new Key[]{ key }, 100); // becomes single-sig account

Amount amount = Amount.get("MCC", "1000");
CreateContractAccountsItem item = gn.currency.extension.getCreateContractAccountsItem(keys, new Amount[]{ amount });

CreateContractAccountsFact fact = gn.currency.extension.getCreateContractAccountsFact(senderAddress, new CreateContractAccountsItem[]{ item });

Operation createContractAccount = gn.getOperation(fact);
createContractAccount.sign(senderPrivateKey);
Withdraw
컨트랙트 계정에 예치된 토큰은 withdraw operation을 통해 인출할 수 있습니다.
/*
import org.mitumc.sdk.Generator;
import org.mitumc.sdk.operation.*;
import org.mitumc.sdk.operation.currency.*;
import org.mitumc.sdk.operation.currency.extension.*;
*/
Generator gn = Generator.get("mitum"); // network id: mitum

String senderPrivateKey = "KzdeJMr8e2fbquuZwr9SEd9e1ZWGmZEj96NuAwHnz7jnfJ7FqHQBmpr";
String senderAddress = "2D5vAb2X3Rs6ZKPjVsK6UHcnGxGfUuXDR1ED1hcvUHqsmca";
String targetAddress = "CY1pkxsqQK6XMbnK4ssDNbDR2K7mitSwdS27DwBjd3Gcmca";

Amount amount1 = Amount.get("MCC", "1000000");
Amount amount2 = Amount.get("PEN", "15000");

WithdrawsItem item = gn.currency.extension.getWithdrawsItem(targetAddress, new Amount[]{ amount1, amount2 }); // getTransfersItem(receiver address, amount list)
WithdrawsFact fact = gn.currency.extension.getWithdrawsFact(senderAddress, new WithdrawsItem[]{ item }); // getTransfersFact(sender address, item list)

Operation withdraws = gn.getOperation(fact);
withdraws.sign(senderPrivateKey);
document, feefi, NFT 모델의 operation을 생성하는 방법은 README 에서 확인할 수 있습니다.

Sign

operation이 정상적으로 블록에 저장되기 위해서는 operation의 서명들이 특정 조건을 만족해야 합니다.
주의해야할 점은 다음과 같습니다.
  • 모든 서명이 계정의 개인키의 서명인가요?

  • 각 signer의 weight들을 모두 합한 값이 계정의 threshold 이상인가요?

물론, 각 operation이 지켜야 할 다른 조건들이 더 있습니다. 하지만 여기서는 (fact)서명에만 집중하겠습니다.
각 키의 weight가 30이고 threshold가 50인 멀티 시그 계정이 있다고 가정해봅시다.
즉, 다음과 같습니다.
  • (pub1, 30)

  • (pub2, 30)

  • (pub3, 30)

  • threshold: 50

이 계정이 operation을 전송하길 원할 때, operation은 서로 다른 signer의 최소 2 개의 fact 서명을 가지고 있어야 합니다.
  1. CASE1: fact signatures signed by pub1’s private key and pub2’s private key

    1. the sum of pub1’s weight and pub2’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  2. CASE2: fact signatures signed by pub2’s private key and pub3’s private key

    1. the sum of pub2’s weight and pub3’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  3. CASE3: fact signatures signed by pub1’s private key and pub3’s private key

    1. the sum of pub1’s weight and pub3’s weight: 60

    2. the sum of weights = 60 > threshold = 50

    3. So the operation with these two fact signatures is available

  4. CASE4: fact signatures signed by pub1’s private key, pub2’s private key, pub3’s private key

    1. the sum of pub1’s weight, pub2’s weight and pub3’s weight: 90

    2. the sum of weights = 90 > threshold = 50

    3. So the operation with these two fact signatures is available

그러므로 조건을 만족하기 위해 각 operation에 여러 개의 signature를 추가해야 합니다. (Operation.sign(private key) 를 사용하세요.)
CASE4의 경우와 같이 weight들의 총합 >= threshold 조건이 지켜지는 한 모든 개인키로 서명하는 것도 가능합니다.
Add Fact Sign to Operation
operation 생성 시 fact 서명을 추가하는 방법 외에 fact 서명을 추가하는 다른 방법이 하나 더 있습니다.
operation에 새 서명을 추가하기 위해 준비해야 할 것은 다음과 같습니다.
  • 서명할 개인키 - 이 개인키는 계정의 키여야 합니다.

  • JsonObject 혹은 외부 JSON 파일 형태의 operation

  • Network ID

우선 Generator 처럼 network id 와 함께 Signer 를 생성합니다.
/*
import org.mitumc.sdk.Signer;
import org.mitumc.sdk.JSONParser;
*/
String id = "mitum";
String key = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";

Signer signer = Signer.get(id, key);
그리고, 서명하세요!
HashMap<String, Object> signed = signer.addSignToOperation("operation.json"); // or JsonObject from Operation JSON instead
아웃풋인 signed는 mitum-java-util의 Operation 객체가 아닙니다. 단지 HashMap 객체입니다.
한 번에 여러 개의 서명을 추가하길 원한다면 signed - HashMap로부터 JsonObject를 다시 만들어 다른 개인키로 생성한 Signer 클래스로 서명해야 합니다.

Details

Get Mitum Keypair
Mitum 키페어 생성 방법을 소개합니다!
시작 전, 중요한 것을 설명하겠습니다.
Mitum의 계정의 주소, 개인키, 공개키는 각자 특별한 타입 접미사를 가지고 있습니다. 그것은 다음과 같습니다.
  • Account Address: mca

  • Private Key: mpr

  • Public Key: mpu

예를 들어, 한 single sign 계정은 다음과 같은 형태를 가집니다.
  • Account Address: 9XyYKpjad2MSPxR4wfQHvdWrZnk9f5s2zc9Rkdy2KT1gmca

  • Private Key: L11mKUECzKouwvXwh3eyECsCnvQx5REureuujGBjRuYXbMswFkMxmpr

  • Public Key: 28Hhy6jwkEHx75bNLmG66RQu1LWiZ1vodwRTURtBJhtPWmpu

키페어를 생성하는 세 가지 방법이 있습니다.
Just Create New Keypair
mitum-java-util가 무작위의 키페어를 생성해줍니다.
Keypar.create() 를 사용하세요.
/*
import org.mitumc.sdk.key.Keypair;
*/
Keypair kp = Keypair.random();

kp.getPrivateKey(); // returns private key of the keypair
kp.getPublicKey(); // returns public key of the keypair
Get Keypair From Your Private Key
이미 개인키를 가지고 있다면 해당 키로부터 키페어를 생성할 수 있습니다.
/*
import org.mitumc.sdk.key.Keypair;
*/
String key = "KzafpyGojcN44yme25UMGvZvKWdMuFv1SwEhsZn8iF8szUz16jskmpr";
Keypair pkp = Keypair.fromPrivateKey(key);
Get Keypair From Your Seed
시드로부터 키페어를 생성할 수도 있습니다. 키페어의 개인키를 기억하지 못하더라도 시드를 통해 복구할 수 있습니다.
문자열 시드 길이는 36 이상이어야 합니다.
/*
import org.mitumc.sdk.key.Keypair;
*/
String seed =  "Thisisaseedfortheexample;Keypair.fromSeed()";
Keypair skp = Keypair.fromSeed(seed);

// or... -----------------------------//
// byte[] bseed = seed.getBytes();
// Keypair skp = Keypair.fromSeed(bseed);
Get Account Address with Keys
계정 주소를 threshold와 계정의 모든 (public key, weight)쌍을 사용해 알아낼 수 있습니다.
하지만 이 방법은 계정의 threshold나 키가 업데이트 되지 않은 경우에만 사용할 수 있습니다.
예제의 계정 정보는 다음과 같습니다.
  • key1: (vmk1iprMrs8V1NkA9DsSL3XQNnUW9SmFL5RCVJC24oFYmpu, 40)

  • key2: (29BQ8gcVfJd5hPZCKj335WSe4cyDe7TGrjam7fTrkYNunmpu, 30)

  • key3: (uJKiGLBeXF3BdaDMzKSqJ4g7L5kAukJJtW3uuMaP1NLumpu, 30)

  • threshold: 100

/*
import org.mitumc.key.Key
import org.mitumc.key.Keys
*/
Key key1 = Key.get("vmk1iprMrs8V1NkA9DsSL3XQNnUW9SmFL5RCVJC24oFYmpu", 40);
Key key2 = Key.get("29BQ8gcVfJd5hPZCKj335WSe4cyDe7TGrjam7fTrkYNunmpu", 30);
Key key3 = Key.get("uJKiGLBeXF3BdaDMzKSqJ4g7L5kAukJJtW3uuMaP1NLumpu", 30);

Keys keys = Keys.get(new Key[]{ key1, key2, key3 }, 100);

String address = keys.getAddress(); // This is the goal!
Major Classes
Generator
Generator 는 Mitum Currency operation 생성을 도와줍니다.
Generator 를 사용하기 전 network id 를 설정해야 합니다.
  • Mitum Currency: Generator.currency

  • Mitum Currency Extension: Generator.currency.extension

  • Mitum Document: Generator.document

  • Mitum Feefi: Generator.feefi

  • Mitum NFT: Generator.nft

/*
import org.mitumc.sdk.Generator;
*/
String id = "mitum";
Generator generator = Generator.get(id);

CurrencyGenerator cgn = generator.currency; // org.mitumc.sdk.operation.currency.CurrencyGenerator;
ExtensionGenerator egn = generator.currency.extension; // org.mitumc.sdk.operation.currency.extension.ExtensionGenerator;
DocumentGenerator dgn = generator.document; // org.mitumc.sdk.operation.document.DocumentGenerator;
FeefiGenerator fgn = generator.feefi; // org.mitumc.sdk.operation.feefi.FeefiGenerator;
NFTGenerator ngn = generator.nft; // org.mitumc.sdk.operation.nft.NFTGenerator;
Generator 가 제공하는 모든 메서드는 다음과 같습니다.
 /* For Mitum Currency */
CreateAccountsItem getCreateAccountsItem(Keys keys, Amount[] amounts);
TransfersItem getTransfersItem(String receiver, Amount[] amounts);
CreateAccountsFact getCreateAccountsFact(String sender, CreateAccountsItem[] items);
KeyUpdaterFact getKeyUpdaterFact(String target, String currency, Keys keys);
TransfersFact getTransfersFact(String sender, TransfersItem[] items);

/* For Mitum Currency Extension */
CreateContractAccountsItem getCreateContractAccountsItem(Keys keys, Amount[] amounts);
WithdrawsItem getWithdrawsItem(String target, Amount[] amounts);
CreateContractAccountsFact getCreateContractAccountsFact(String sender, CreateContractAccountsItem[] items);
WithdrawsFact getWithdrawsFact(String sender, WithdrawsItem[] items);

/* For Mitum Document */
Generator.document.getCreateDocumentsItem(Document document, String currencyId);
Generator.document.getUpdateDocumentsItem(Document document, String currencyId);
Generator.document.getCreateDocumentsFact(String sender, CreateDocumentsItem[] items);
Generator.document.getUpdateDocumentsFact(String sender, UpdateDocumentsItem[] items);

/* For Blocksign */
Generator.document.blocksign.user(String address, String signCode, boolean signed);
Generator.document.blocksign.document(String documentId, String owner, String fileHash, BlockSignUser creator, String title, String size, BlockSignUser[] signers);
Generator.document.blocksign.getSignDocumentsItem(String documentId, String owner, String currencyId);
Generator.document.blocksign.getSignDocumentsFact(String sender, SignDocumentsItem[] items);DocumentsFact(String sender, BlockCityItem<T>[] items);

/* For Blockcity */
Candidate candidate(String address, String nickname, String manifest, int count);
UserStatistics userStatistics(int hp, int strength, int agility, int dexterity, int charisma, int intelligence, int vital);
Document userDocument(String documentId, String owner, int gold, int bankGold, UserStatistics statistics);
Document landDocument(String documentId, String owner, String address, String area, String renter, String account, String rentDate, int period);
Document voteDocument(String documentId, String owner, int round, String endTime, Candidate[] candidates, String bossName, String account, String office);
Document historyDocument(String documentId, String owner, String name, String account, String date, String usage, String app);

/* For Mitum Feefi */
PoolRegisterFact getPoolRegisterFact(String sender, String target, Amount initialFee, String incomingCid, String outgoingCid, String currency);
PoolPolicyUpdaterFact getPoolPolicyUpdaterFact(String sender, String target, Amount fee, String poolId, String currency);
PoolDepositsFact getPoolDepositsFact(String sender, String pool, String poolId, Amount amount);
PoolWithdrawFact getPoolWithdrawFact(String sender, String pool, String poolId, Amount[] amounts);

/* For Mitum NFT */
NFTSigner signer(String account, int share, boolean signed);
NFTSigners signers(int total, NFTSigner[] signers);
CollectionRegisterForm collectionRegisterForm(String target, String symbol, String name, int royalty, String uri, String[] whites);
CollectionPolicy collectionPolicy(String name, int royalty, String uri, String[] whites);
MintForm mintForm(String hash, String uri, NFTSigners creators, NFTSigners copyrighters);

MintItem getMintItem(String collection, MintForm form, String currency);
NFTTransferItem getTransferItem(String receiver, NFTID nid, String currency);
BurnItem getBurnItem(NFTID nid, String currency);
NFTSignItem getSignItem(String qualification, NFTID nid, String currency);
ApproveItem getApproveItem(String approved, NFTID nid, String currency);
DelegateItem getDelegateItem(String collection, String agent, String mode, String currency);

CollectionRegisterFact getCollectionRegisterFact(String sender, CollectionRegisterForm form, String currency);
CollectionPolicyUpdaterFact getCollectionPolicyUpdaterFact(String sender, String collection, CollectionPolicy policy, String currency);
MintFact getMintFact(String sender, MintItem[] items);
NFTTransferFact getTransferFact(String sender, NFTTransferItem[] items);
BurnFact getBurnFact(String sender, BurnItem[] items);
NFTSignFact getSignFact(String sender, NFTSignItem[] items);
ApproveFact getApproveFact(String sender, ApproveItem[] items);
DelegateFact getDelegateFact(String sender, DelegateItem[] items);

/* Common */
Operation getOperation(OperationFact fact);
Operation getOperation(OperationFact fact, String memo);
HashMap<String, Object> getSeal(String signKey, Operation[] operations);
HashMap<String, Object> getSeal(String signKey, JsonObject[] operations);
HashMap<String, Object> randomKeys();
HashMap<String, Object> randomKeys(int numOfKeys);
Signer
Signer 는 이미 생성된 operation에 새로운 fact 서명을 추가할 때 사용합니다.
Generator 와 같이 network id 가 설정되어야 합니다.
서명에 사용할 개인키도 준비해야 합니다.
Signer 는 오직 하나의 메서드를 제공합니다.
HashMap<String, Object> addSignToOperation(JsonObject operation);
HashMap<String, Object> addSignToOperation(String operationPath);
Signer 의 정확한 사용 방법은 ‘Make Your First Operation - Sign’로 돌아가서 확인하세요.
JSONParser
이 클래스는 편의를 위해 개발되었습니다.
Operation 을 내보내거나 JSON 형식으로 출력하기 위해 다른 패키지를 사용하길 원한다면 굳이 mitum-java-util의 JSONParser 를 사용할 필요는 없습니다.
JsonObject getObjectFromJsonFile(String fpName);
JsonObject getObjectFromHashMap(HashMap<String, Object> target);
void writeJsonFileFromJsonObject(JsonObject target, String fpName);
void writeJsonFileFromHashMap(HashMap target, String fpName);
HashMap<String, Object> mergeOperations(JsonObject[] operations);
HashMap<String, Object> mergeOperations(HashMap<String, Object>[] operations);
/*
import org.mitumc.sdk.JSONParser;
*/
// ... omitted
// ... create operations
// ... refer to above `Make Your First Operation`
// ... suppose you have already made operations - createAccount, keyUpdater, transfer and a seal - seal

JSONParser.writeJsonFileFromHashMap(createAccount.toDict(), 'createAccount.json'); // writeJsonFileFromHashMap(HashMap, filePath)
JSONParser.writeJsonFileFromHashMap(keyUpdater.toDict(), 'keyUpdater.json');
JSONParser.writeJsonFileFromHashMap(transfer.toDict(), 'transfer.json');
JSONParser.writeJsonFileFromHashMap(seal, 'seal.json');

About Time Stamp

Expression of Time Stamp

블록, seal, 서명 등에서 mitum은 yyyy-MM-dd HH:mm:ss.* +0000 UTC 표현과 yyyy-MM-ddTHH:mm:ss.*Z 을 표준으로 사용합니다.
다른 timezone은 허용되지 않습니다! 오직 +0000 timezone 을 사용하세요.
예를 들어,
  • timestamp를 block/seal/fact_sign hash 생성을 위한 byte 포맷으로 변환할 경우,

문자열 '2021-11-16 01:53:30.518 +0000 UTC'을 byte 포맷으로 변환합니다.
  • timestamp를 block, seal, fact_sign나 기타 json value에 추가하여 파일로 출력할 경우,

문자열 '2021-11-16T01:53:30.518Z'을 json에 추가합니다.
operation hash를 생성하기 위해, mitum은 network id, fact hash의 byte array와 각 fact_sign의 byte array를 연결합니다.
fact_sign의 byte array를 생성하기 위해, mitum은 signer, signature digest, signed_at의 byte array를 연결합니다.
signed_at이 byte array로 변환될 때 문자열 yyyy-MM-dd HH:mm:ss.* +0000 UTC 를 byte 형식으로 변환한다는 사실에 주의하세요. 반면 이 문자열은 json의 signed_at 키에 추가 시 yyyy-MM-ddTHH:mm:ss.*Z 형태가 됩니다.

How many decimal places to be expressed?

한 가지 더 주의해야 할 점이 있습니다.
우선, timestampe의 ‘초’자리의 소수점 자리수에 대해 걱정할 필요는 없습니다.
게다가, . 와 그 아래의 소수점 자리를 적지 않아도 되는 경우에는 없이 사용할 수도 있습니다.
하지만 timestamp를 byte 형식으로 바꿀 때에는 불필요한 소수점 0 가 없는 문자열을 사용해야 합니다.
For example,
  • 2021-11-16T01:53:30.518Z 는 아무런 차이가 없는 2021-11-16 01:53:30.518 +0000 UTC 로 변환됩니다.

  • 2021-11-16T01:53:30.510Z 는 hash 생성 시에는 반드시 2021-11-16 01:53:30.51 +0000 UTC 로 변환하여 사용해야 합니다.

  • 2021-11-16T01:53:30.000Z 는 hash 생성 시에는 반드시 2021-11-16T01:53:30 +0000 UTC 로 변환하여 사용해야 합니다.

json 값으로 포함되는 불필요한 0 이 있는 모든 문자열 timestamp들은 block, seal, operation 처리에 영향을 주지 않습니다.
단지 timestamp의 byte array가 필요한 경우에만 주의하십시오.