Introduction
DID micro service provides API for exchanges to allow their customers to register DID and bind DID to customer’s wallet.
Exchanges can implement the same feature according to this documemt.
Related MVS commands:
getnewaddress
registerdid
didchangeaddress
getdid
getpublickey
getnewmultisig
sendrawtx
send
For details of these command, please refer to API Document。
User Case
In the following user case, two actors are involed exchange and user Alice。
User requests registering an DID
Alice request registering an DID named Alias@Alice on exchange’s website or app.
Exchange registers DID
Exchange generates a new address by getnewaddress and registers DID named Alias@Alice to it.
User binds DID to user’s wallet
Generate multi-signature address
Exchange andAliceget public-key of an address of their account bygetpublickey. Exchange andAliceswap the public-keys and generate multi-signature addresses bygetnewmultisigwith the public-keys and parameterm:nvalued1:2.Exchange transfers DID to the multi-signature address
Exchange creates a transcation bydidchangeaddressto transfer DID namedAlias@Aliceto the multi-signature address. Exchange broadcasts the transcation bysendrawtx.User transfers DID from the multi-signature address to wallet
Alicecreates a transcation bydidchangeaddressto transfer DID namedAlias@Alicefrom the multi-signature address.Alicebroadcasts the transcation bysendrawtx.Confirmation
Aliceconfirms the result bygetdid.
DID micro service
DID micro service provides API for exchanges to process the business logics above.
Exchange registers DID
Exchange generates a new address bygetnewaddressand registers DID to it. Exchange saves user’s account ID, DID name and address by micro service apisavedid.Exchange generates a multi-signature address
Exchange queries DID name and address with user’s account ID by micro service apiquerydidwhen user requests binding DID to user’s wallet. Exchange gets the public key of DID address bygetpublickey. After exchange and user swaps their public-keys, exchange generates a multi-signature addresses bygetnewmultisig.Exchange tansfers DID to the multi-signature address
Exchange creates a transcation bydidchangeaddressto transfer DID to the multi-signature address. Exchange broadcasts the transcation bysendrawtx.
Implementation
User requests registering an DID
Alice request registering an DID named Alias@Alice on exchange’s website or app.
Exchange registers DID
Exchange generates a new address
MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rjbygetnewaddress.// Request
curl -X POST --data '{
"jsonrpc":"2.0",
"id":8,
"method":"getnewaddress",
"params":[
"Exchange",
"exchangepwd",
{
"number": 1
}
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 8,
"jsonrpc" : "2.0",
"result" :
{
"addresses" :
[
"MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj"
]
}
}Exchange sends
100000000satoshi(1 ETP) to the new address as fee of registering DID.// Request
curl -X POST --data '{
"id":125,
"jsonrpc":"2.0",
"method":"send",
"params":[
"Exchange",
"exchangepwd",
"MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj",
"100000000"
]
}' 127.0.0.1:8820/rpc/v2
// Response
{
// omit...
}Exchange registers DID named
Alias@Aliceto the new address byregisterdid.// Request
curl -X POST -d '{
"id":25,
"jsonrpc":"2.0",
"method":"registerdid",
"params":[
"Exchange",
"exchangepwd",
"MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj",
"Alias@Alice"
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 25,
"jsonrpc" : "2.0",
"result" :
{
"transaction" :
{
"hash" : "c350ab69320dc07f7157ae53f82b12c0a0fabafd0c9a381591de22cd24401b7f",
"inputs" :
[
{
"address" : "MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj",
"previous_output" :
{
"hash" : "9a3e19510089fdc14dd3f0a5e8d252b9271dddfbc41651936bac6c406b8ad15c",
"index" : 0
},
"script" : "[ 304402205f2b347ded297c384f4b28187d41abafd46f254fbac18f856d5e7337f8e83ef202206775b25a9f5820689dae59df0789e7fd5787a68238914e0ac70504d47e1ad0ba01 ] [ 031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321 ]",
"sequence" : 4294967295
}
],
"lock_time" : "0",
"outputs" :
[
{
"address" : "MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj",
"attachment" :
{
"address" : "MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj",
"symbol" : "Alias@Alice",
"type" : "did-register"
},
"index" : 0,
"locked_height_range" : 0,
"script" : "dup hash160 [ 89d56e08bdbcfe40eb7f3b34fe21253669c828b1 ] equalverify checksig",
"value" : 0
},
{
"address" : "MGqHvbaH9wzdr6oUDFz4S1HptjoKQcjRve",
"attachment" :
{
"type" : "etp"
},
"index" : 1,
"locked_height_range" : 0,
"script" : "dup hash160 [ 61fde3bd4e6955c99b16de2d71e2a369888a1c0b ] equalverify checksig",
"value" : 80000000
}
],
"version" : "4"
}
}
}Exchange saves user’s account ID, DID name and address by micro service api
savedid.
User transfers DID to wallet
Exchange queries DID
Alias@Aliceand addressMLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rjwith user’s account ID by micro service apiquerydidwhen user requests binding DID to user’s wallet.Exchange gets the public-key
031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321of addressMLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rjbygetpublickey. Exchange displays the public-key toAliceandAlicerecords it to generate a multi-signature address later.// Request
curl -X POST --data '{
"jsonrpc":"2.0",
"method":"getpublickey",
"id":5,
"params":[
"Exchange",
"exchangepwd",
"MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj"
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 5,
"jsonrpc" : "2.0",
"result" :
{
"address" : "MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj",
"public-key" : "031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321"
}
}Alicegets the public-key0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0aof address that DID binds to bygetpublickey.Alicecommits this public-key to exchange.// Request
curl -X POST --data '{
"jsonrpc":"2.0",
"method":"getpublickey",
"id":5,
"params":[
"Alice",
"alicepwd",
"MSqhPipeAZ1Ua9GfNbBi65RPdT7x4iHvwF"
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 5,
"jsonrpc" : "2.0",
"result" :
{
"address" : "MSqhPipeAZ1Ua9GfNbBi65RPdT7x4iHvwF",
"public-key" : "0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a"
}
}Generate multi-signature address
Now, both exchange andAlicehave enough information to generate multi-signature address. They generate the same multi-signature address bygetnewmultisigwith public-keys and paramentm:nvalued1:2.Exchange generates a multi-signature address
35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF:curl -X POST --data '{
"id":7,
"jsonrpc":"2.0",
"method":"getnewmultisig",
"params":[
"Exchange",
"exchangepwd",
{
"publickey": [
"0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a"
],
"selfpublickey": "031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321",
"signaturenum": 1,
"publickeynum": 2
}
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 7,
"jsonrpc" : "2.0",
"result" :
{
"address" : "35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF",
"description" : "",
"index" : 1,
"m" : 1,
"multisig-script" : "1 [ 031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321 ] [ 0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a ] 2 checkmultisig",
"n" : 2,
"public-keys" :
[
"031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321",
"0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a"
],
"self-publickey" : "031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321"
}
}Alicegenerates a multi-signature address35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF:curl -X POST --data '{
"id":7,
"jsonrpc":"2.0",
"method":"getnewmultisig",
"params":[
"Alice",
"alicepwd",
{
"publickey": [
"031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321"
],
"selfpublickey": "0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a",
"signaturenum": 1,
"publickeynum": 2
}
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 7,
"jsonrpc" : "2.0",
"result" :
{
"address" : "35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF",
"description" : "",
"index" : 1,
"m" : 1,
"multisig-script" : "1 [ 031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321 ] [ 0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a ] 2 checkmultisig",
"n" : 2,
"public-keys" :
[
"031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321",
"0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a"
],
"self-publickey" : "0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a"
}
}
Exchange transfers DID to the multi-signature address
Exchange sends
10000satoshi(0.0001 ETP) to the multi-signature address as fee of transfering DID later.// Request
curl -X POST --data '{
"id":125,
"jsonrpc":"2.0",
"method":"send",
"params":[
"Exchange",
"exchangepwd",
"35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF",
"10000"
]
}' 127.0.0.1:8820/rpc/v2
// Response
{
// 略...
}Exchange creates a transcation by
didchangeaddressto transfer DIDAlias@Aliceto the multi-signature address35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF. Exchange broadcasts the transcation bysendrawtx.Exchange creates a transcation:
// Request
curl -X POST -d '{
"id":25,
"jsonrpc":"2.0",
"method":"didchangeaddress",
"params":[
"Exchange",
"exchangepwd",
"35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF",
"Alias@Alice"
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 25,
"jsonrpc" : "2.0",
"result" : "0400000002c3acf1058e8ae5341fed5b944fe86b83edecbadc5d386e6a968af6eff6378ae7000000009300483045022100c1cbb2235c057e3fac37d4884a3929009336978d5a1feba27acad3012d7e1f550220009a6385d42d28964ccc85c0416aa448933213875901c64695ac7e70b79f3c51014c475121031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321210344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a52aeffffffff7f1b4024cd22de9115389a0cfdbafaa0c0122bf853ae57717fc00d3269ab50c3000000006b483045022100f88ea6c345e1164e7bc2331ea11bf0bb795ad104b02b1da394d976751de378ba02203f02e841e27aae877ff1bcd22fd72737586539e3d40e3451661ac32ab686e7690121031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321ffffffff01000000000000000017a9142a74a23b4ed1bb90f575e73c0208106d37eb653a870100000004000000020000000b416c69617340416c6963652233355a573254465468614b3936447a775277726671355352483275377a664b54434600000000"
}Exchange broadcasts the transcation:
// Request
curl -X POST -d '{
"id":25,
"jsonrpc":"2.0",
"method":"sendrawtx",
"params":[
"0400000002c3acf1058e8ae5341fed5b944fe86b83edecbadc5d386e6a968af6eff6378ae7000000009300483045022100c1cbb2235c057e3fac37d4884a3929009336978d5a1feba27acad3012d7e1f550220009a6385d42d28964ccc85c0416aa448933213875901c64695ac7e70b79f3c51014c475121031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321210344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a52aeffffffff7f1b4024cd22de9115389a0cfdbafaa0c0122bf853ae57717fc00d3269ab50c3000000006b483045022100f88ea6c345e1164e7bc2331ea11bf0bb795ad104b02b1da394d976751de378ba02203f02e841e27aae877ff1bcd22fd72737586539e3d40e3451661ac32ab686e7690121031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321ffffffff01000000000000000017a9142a74a23b4ed1bb90f575e73c0208106d37eb653a870100000004000000020000000b416c69617340416c6963652233355a573254465468614b3936447a775277726671355352483275377a664b54434600000000"
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 25,
"jsonrpc" : "2.0",
"result" :
{
"hash" : "a981e820071c852710c05bdb70ec2da0da0d877575947aedbcf3ff1d3b7f56c9"
}
}
Alicetransfers DID from the multi-signature addressAlicecreates a transcation bydidchangeaddressto transfer DIDAlias@Alicefrom the multi-signature address35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF.Alicebroadcasts the transcation bysendrawtx.Alicecreates a transcation:// Request
curl -X POST -d '{
"id":25,
"jsonrpc":"2.0",
"method":"didchangeaddress",
"params":[
"Alice",
"alicepwd",
"MSqhPipeAZ1Ua9GfNbBi65RPdT7x4iHvwF",
"Alias@Alice"
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 25,
"jsonrpc" : "2.0",
"result" : "0400000002c9567f3b1dfff3bced7a947575870ddaa02dec70db5bc01027851c0720e881a9000000009300483045022100adb80306458db15f8e82108f92a3ecf9d0dd221f89386b1d006a09b88dba243c022007a5198bb84f203b6a91bc2fcc7fd5413cfc0e7982dabdc89feb2f3a5cf3405c014c475121031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321210344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a52aeffffffffb6a654253b99292f7ce585fc718c0e28dbe730c79dded3eb373f9b51ce9ddd0e000000006a47304402205beb823ab2395e8ceecd1595327f3d1f8fe9bec12e6d1e71df94acf29d168bf502204152096109155468fd6f501e5494ac947fba2e7f313ec2b398e6b3aec5eeb59701210344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0affffffff0200000000000000001976a914cfc2bcbdc96854fe00dbe86db689fd1ea918bdd888ac0100000004000000020000000b416c69617340416c696365224d53716850697065415a3155613947664e6242693635525064543778346948767746f07be111000000001976a914cfc2bcbdc96854fe00dbe86db689fd1ea918bdd888ac010000000000000000000000"
}Alicebroadcasts the transcation:// Request
curl -X POST -d '{
"id":25,
"jsonrpc":"2.0",
"method":"sendrawtx",
"params":[
"0400000002c9567f3b1dfff3bced7a947575870ddaa02dec70db5bc01027851c0720e881a9000000009300483045022100adb80306458db15f8e82108f92a3ecf9d0dd221f89386b1d006a09b88dba243c022007a5198bb84f203b6a91bc2fcc7fd5413cfc0e7982dabdc89feb2f3a5cf3405c014c475121031c7ac7f12a05ea4952289801fa52142aa421f11efe8ab7090fb823562156a321210344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a52aeffffffffb6a654253b99292f7ce585fc718c0e28dbe730c79dded3eb373f9b51ce9ddd0e000000006a47304402205beb823ab2395e8ceecd1595327f3d1f8fe9bec12e6d1e71df94acf29d168bf502204152096109155468fd6f501e5494ac947fba2e7f313ec2b398e6b3aec5eeb59701210344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0affffffff0200000000000000001976a914cfc2bcbdc96854fe00dbe86db689fd1ea918bdd888ac0100000004000000020000000b416c69617340416c696365224d53716850697065415a3155613947664e6242693635525064543778346948767746f07be111000000001976a914cfc2bcbdc96854fe00dbe86db689fd1ea918bdd888ac010000000000000000000000"
]
}' http://127.0.0.1:8820/rpc/v2
// Response
{
"id" : 25,
"jsonrpc" : "2.0",
"result" :
{
"hash" : "efbd03e1e25fb7b5a4b153bda5f7fe34bc1a8028f751ee14c93d3a398fa71d8d"
}
}
Confirmation
Aliceconfirms the result bygetdid.// Request
curl -X POST --data '{
"jsonrpc":"2.0",
"method":"getdid",
"id":42,
"params":["Alias@Alice"]
}' http://127.0.0.1:8820/rpc/v2/
// Response
{
"id" : 42,
"jsonrpc" : "2.0",
"result" :
{
"addresses" :
[
{
"address" : "MSqhPipeAZ1Ua9GfNbBi65RPdT7x4iHvwF",
"status" : "current"
},
{
"address" : "35ZW2TFThaK96DzwRwrfq5SRH2u7zfKTCF",
"status" : "history"
},
{
"address" : "MLTxV5JAu5sFhQmJYNRmPuu31CkNWrF5rj",
"status" : "history"
}
],
"did" : "Alias@Alice"
}
}
Implementation with mvs_rpc_python
Please refer to exchange_register_avatar.
Key code.
account_name = 'Exchange' # account name of exchange
account_pwd = 'exchangepwd' # password of account
if __name__ == '__main__':
print('Exchange register evatar example')
#===========================================================================
# register DID
#===========================================================================
# get DID from user
did = input('Please input the name of DID:')
print('user want to register DID: {}'.format(did))
# generate new address
address = generate_new_address(account_name, account_pwd)
if None == address:
print('Failed to generate new address')
sys.exit(0)
print("generate a new address: {}".format(address))
# send 1 ETP to the new address
errmsg = send_etp(account_name, account_pwd, address, 100000000)
if None != errmsg:
print("Failed to send ETP to {}. error: {}".format(address, errmsg))
sys.exit(0)
# register DID to the new address
errmsg = register_did(account_name, account_pwd, address, did)
if None != errmsg:
print("Failed to register DID {} to {}. error: {}".format(did, address, errmsg))
sys.exit(0)
if wait_mining(did, lambda x : get_did(x) == None):
sys.exit(0)
print("** Successfully registered did {} to {}\n".format(did, address))
#===========================================================================
# transfer DID
#===========================================================================
# get public key from user
user_public_key = input("Please input user's public key:")
print("User's public key: {}".format(user_public_key))
# get public key of the new address
self_public_key = get_public_key(account_name, account_pwd, address)
if None == address:
print('Failed to get public key from address {}'.format(address))
sys.exit(0)
print("the public key of the address: {}".format(self_public_key))
# generate multisig address
multisig_address = generate_multisig_address(
account_name, account_pwd, self_public_key, user_public_key)
if None == multisig_address:
print('Failed to generate multisig address {}'.format(address))
sys.exit(0)
print("generate a multisig address: {}".format(multisig_address))
# send 0.0001 ETP to the multisig address
print("sending etp to multisig address")
errmsg = send_etp(account_name, account_pwd, multisig_address, 10000)
if None != errmsg:
print("Failed to send ETP to {}. error: {}".format(address, errmsg))
sys.exit(0)
if wait_mining(multisig_address, lambda x : get_etp(multisig_address) == 0):
sys.exit(0)
# transfer DID to the multisig address
print("transfering did to multisig address")
rawtx = transfer_did(account_name, account_pwd, multisig_address, did)
if None == rawtx:
print("Failed to transfer DID {} to {}.\nerror: {}".format(did, multisig_address, errmsg))
sys.exit(0)
errmsg = broadcast_rawtx(rawtx)
if None != errmsg:
print("Failed to broadcast rawtx {}. error: {}".format(rawtx, errmsg))
sys.exit(0)
if wait_mining([did, multisig_address], lambda x : get_did(x[0])[0]['address'] != x[1]):
sys.exit(0)
print("** Successfully transfered did {} to {}".format(did, multisig_address))Demo:
Exchange register evatar example
Please input the name of DID:'avatar01@Alice'
user want to register DID: avatar01@Alice
generate a new address: MUfeU351P7ipuUFJcotzQzDesKHHpuiFpA
wait for miner to package
** Successfully registered did avatar01@Alice to MUfeU351P7ipuUFJcotzQzDesKHHpuiFpA
Please input user's public key:"0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a"
User's public key: 0344befcd59670651a6441c00ef26caa104bab8ff9e5ec3f6e9b65bac9194cad0a
the public key of the address: 034354fb24938a6b061341e9fdae6b35e3391958c52dccdfc27213ae3ae68288b7
generate a multisig address: 3H62VSQPshYgxmDqCUbyZcaPCenLfJQrUH
sending etp to multisig address
wait for miner to package
transfering did to multisig address
wait for miner to package
** Successfully transfered did avatar01@Alice to 3H62VSQPshYgxmDqCUbyZcaPCenLfJQrUH