Package: sdk
seq | definition | functionality |
---|---|---|
1 | Init( ethNodeAddr string, keyServiceAddr string, protocolAddr string, tokenAddr string, fromBlock uint64, ipfsNodeAddr string, ) error |
Before using scryinfo protocol layer SDK you need to initialize all SDK ethNodeAddr: Eth node address keyServiceAddr: Key service address protocolAddr: Protocol contract address tokenAddr: token address fromBlock: event scan origin block, default setting is 0 ipfsNodeAddr: IPFSnodeaddress |
Package: sdk/scryclient
seq | definition | functionality |
---|---|---|
1 | CreateScryClient(password string) (*ScryClient, error) | After API deployment success,a ScryClient will be created(such as named scryClient), including public&private key account or creator, private key will be stored after encryption User can get account address after visiting scryClient.Account.Address password: The password of account to be created, please keep carefully |
2 | SubscribeEvent(eventName string, callback chainevents.EventCallback) | ScryClient can order certain event on chain by deploying this API When event comes it will trigger certain callback function. Event format can be ordered is: DataPublish TransactionCreate Buy ReadyForDownload TransactionClose Approval |
3 | Authenticate(password string) (bool, error) | Verify user password is correct or not password: Password to be verified |
4 | TransferEthFrom(from common.Address, password string, value *big.Int) error | Transfer ETH from address called “from” to this client from: Origin account password: Origin account password value: Amount to be transferred, unit: 1 wei |
5 | TransferTokenFrom(from common.Address, password string, value *big.Int) error | Transfer Token from address called “from” to this client from: Origin account password: origin account password, used for transaction signature value: Amount to be transferred, unit: 1 token |
6 | GetEth(owner common.Address) (*big.Int, error) | Get ETH amount from account address called owner, unit: 1 wei owner: account address |
7 | GetScryToken(owner common.Address) (*big.Int, error) | Get Token amount from from account address called owner, unit:1 token owner: account address |
Package: sdk/scryclient/chaininterfacewrapper
seq | definition | functionality |
---|---|---|
1 | Publish( txParams *op.TransactParams, price *big.Int, metaData []byte, proofDatas [][]byte, proofNum int, descriptionData []byte ) (string, error) |
Publish data to IPFS and store source id returned from IPFS in blockchain contracts The first return value from this API is publishId,type is string txParams:blockchain transaction parameters price: data price, unit: 1 t oken metaData: Data to be sold proofDatas: proof of data piece to verify data authentication proofNum: Array size of proof of data piece descriptionData : Data description, such as title, keyword etc. Specified meaning should be decided by application layer When all data is published to IPFS and blockchain , it will send DataPublish event to all users. DataPublish event is transmitted with Json format, please refer to Event API |
2 | ApproveTransfer(txParams *op.TransactParams,spender common.Address, value *big.Int) error | Admit address spender transfer token from deployment address of this API txParams :Blockchain transaction parameters spender : Transfer admitted origin address value :Transfer amount admitted, unit:1 token, should be higher than/equal to data to be purchased In this process, chain will send Approval event to deployer after getting request,please refer to Event API |
3 | PrepareToBuy(txParams *op.TransactParams,publishId string) error | Buyers are ready to buy data and hope to get data verification ID Before deploying this API, buyers should deploy ApproveTransfer API first and admit contract transfer mortagage from buyers address txParams : Blockchain transaction parameter publishId : Same as above Chain will send TransactionCreate event to buyers after getting request TransactionCreate event is transmitted with Json format, please refer to Event API |
4 | BuyData(txParams *op.TransactParams,txId *big.Int)error | Buyers buy data txParams : Blockchain transaction parameters txId: : Transaction ID this time, obtained from transactionId array in TransactionCreate event Chain will sent Buy event to sellers after getting request Buy event is transmitted with Json format, please refer to Event API |
5 | SubmitMetaDataIdEncWithBuyer(txParams *op.TransactParams, txId *big.Int, encyptedMetaDataId []byte) error | Sellers upload metaDataId of data to be purchased, this ID is encrypted with buyers public key txParams: Blockchain transaction parameters txId: transaction ID this time, obtained from transactionId array in Buy event encyptedMetaDataId: metaDataId encrypted with buyers public key Chain will send ReadyForDownload event to buyers after getting request Buyers get metaDataId and decrypted with private key, then get the real meta data ID,can download data from IPFS ReadyForDownload event is transmitted with Json format, please refer to Event API |
6 | ConfirmDataTruth(txParams *op.TransactParams, txId *big.Int, truth bool) error | Buyers confirm data authentication txParams: Blockchain transaction parameters txId: Transaction ID this time, obtained from transactionId in Buy event truth:Whether the data is ture or not Chain will send TransactionClose event to all users after getting the request and then end the transaction If the data is true, contract will send the mortagage from buyers to sellers TransactionClose event is transmitted with Json format, please refer to Event API |
Package: sdk/util/accounts
seq | definition | functionality |
---|---|---|
1 | Encrypt(plainText []byte, address string) ([]byte, error) | Encrypt plaintext with the public key of user address plainText: plaintext data address: user address |
2 | Decrypt(cipherText []byte, address string, password string) ([]byte, error) | Decrypt the ciphertext with the private key of user’s address cipherText: cipher text address: user address password: user password |
3 | ReEncrypt(cipherText []byte, address1, address2, password string) ([]byte, error) | The encrypted data cipherText is decrypted and then encrypted using the public key of the second user address. cipherText: ciphertext data address1: decrypt user address address2: encrypted user address password: decrypt user password |
All events are transmitted in JSON format.
seq | definition | functionality |
---|---|---|
1 | DataPublish | { "despDataId": "QmhKnroYBFp", //Data description ID, based on wich the description of the data for sale can be obtained from IPFS "price": 1000,//Price for sale "publishId": "155212056", //the released ID is the same as the first return value of Publish "seqNo": "155212057", "users": "[0xxxx]" } |
2 | Approval | { "owner": "0x3Ab0dAA324", //authorized person "spender": "0x3c4d26E91", // authorized pperson "value": 1600 //has been granted } |
3 | TransactionCreate | { "proofIds":[[211, 159], [170, 49]], //data proof ID "publishId": "1552121", "seqNo": "15521219", "transactionId": 4, //transaction ID "users":["0xxxx"] } |
4 | Buy | { "metaDataIdEncSeller": "SdWeLSqpSyhGA==", //Metadata ID encrypted with the seller's public key "publishId": "1552121827295982593-913139", //Data release ID "seqNo": "1552121924035218179-67679122","transactionId": 4, //Transaction ID "users": ["0xxxx"] } |
5 | ReadyForDownload | { "metaDataIdEncBuyer": "tql/mAZY/z0aR2g==", //Metadata ID encrypted with the buyer’s public key "seqNo": "1552126832692923242-89400636", "transactionId": 4, //Transaction ID "users":["0xxxx"] } |
6 | TransactionClose | { "seqNo": "1552126873209063970-5512851552272651527", "transactionId": 4, //Transaction ID "users": ["0xxxx"] } |
func main() {
wd, _ := os.Getwd()
err := sdk.Init(
"http://192.168.1.12:8545/",
"192.168.1.6:48080",
protocolContractAddr,
tokenContractAddr,
0,
"/ip4/192.168.1.6/tcp/5001",
wd+"/testconsole.log",
"scryapp1")
......
}
Second step: Create general account, transfer Eth and token from super account to this account for transaction
The system has a built-in super account. The account address and password are shown in the example code Normal accounts need to consume gas and token for trading, so users must first transfer from super account to ETH and token
seller := scryclient.NewScryClient(address)
buyer := scryclient.NewScryClient(address)
// subscribe events
seller.SubscribeEvent("DataPublish", onPublish)
seller.SubscribeEvent("Buy", onPurchase)
seller.SubscribeEvent("TransactionCreate", onTransactionCreate)
seller.SubscribeEvent("TransactionClose", onClose)
// Approve success if buyer received onApprovalBuyerTransfer notification
buyer.SubscribeEvent("Approval", onApprovalBuyerTransfer)
buyer.SubscribeEvent("TransactionCreate", onTransactionCreate)
buyer.SubscribeEvent("ReadyForDownload", onReadyForDownload)
buyer.SubscribeEvent("TransactionClose", onClose)
func SellerPublishData(supportVerify bool) {
//pending metadata
metaData := []byte("magic meta data test")
//some metadata fragments: used to prove the authenticity of metadata
proofData := [][]byte{{'4', '5', '6', '3'}, {'2', '2', '1'}}
//metadata description data
despData := []byte{'7', '8', '9', '3'}
txParam := chainoperations.TransactParams{
From: common.HexToAddress(seller.Account.Address),
Password: keyPassword,
}
cif.Publish(
&txParam,
big.NewInt(1000),
metaData,
proofData,
2,
despData,
)
}
Buyers get data publish notification and description ID for this data, then they can download data description info from IPFS
func onPublish(event events.Event) bool {
//data release ID
publishId = event.Data.Get("publishId").(string)
//description data ID
despDataId := event.Data.Get("despDataId").(string)
//price
price := event.Data.Get("price").(*big.Int)
return true
}
Buyers are interested in this data after seeing description info,then they set mortagage amount and admit smart contract transfer Token from their account for mortagage
func BuyerApproveTransfer() {
//buyerPassword: the account password of buyer
txParam := chainoperations.TransactParams{
From: common.HexToAddress(buyer.Account.Address),
Password: buyerPassword,
}
//protocolContractAddr is the protocol layer contract address
//the amount of the deposit must be greater than or equal to the data price, otherwise the purchase operation will fail
err := cif.ApproveTransfer(&txParam,
common.HexToAddress(protocolContractAddr),
big.NewInt(1000))
if err != nil {
fmt.Println("BuyerApproveTransfer:", err)
}
}
func PrepareToBuy(publishId string) {
txParam := chainoperations.TransactParams{
From: common.HexToAddress(buyer.Account.Address),
Password: buyPassword,
}
err := cif.PrepareToBuy(&txParam, publishId)
if err != nil {
fmt.Println("failed to prepareToBuy, error:", err)
}
}
func onTransactionCreate(event events.Event) bool {
fmt.Println("seller: onTransactionCreated:", event)
//transaction ID
txId = event.Data.Get("transactionId").(*big.Int)
return true
}
Buyers get data verification ID and they can download data verification results from IPFS with this ID to judge whether this data is exactly what they want
func onTransactionCreate(event events.Event) bool {
//transaction ID
txId = event.Data.Get("transactionId").(*big.Int)
//proof IDs
proofIDs := event.Data.Get("proofIds").([][32]byte)
return true
}
func Buy(txId *big.Int) {
//the seller needs to order the Buy event in order to receive the buyer’s purchase
seller.SubscribeEvent("Buy", onPurchase)
//buyerPassword is the account password of the buyer
txParam := chainoperations.TransactParams{
From: common.HexToAddress(buyer.Account.Address),
Password: buyerPassword,
}
//txId is transaction ID
err := cif.BuyData(&txParam, txId)
if err != nil {
fmt.Println("failed to buyData, error:", err)
}
}
Sellers get notifications of data transaction and generate meta data id encrypted with buyers public key, then send it to contract
func onPurchase(event events.Event) bool {
fmt.Println("onPurchase:", event)
//meta data is encrypted with the seller’s public key
metaDataIdEncWithSeller = event.Data.Get("metaDataIdEncSeller").([]byte)
//buyer address
buyerAddr := event.Data.Get("buyer").(common.Address)
var err error
//metaDataIdEncWithBuyer: meta data is encrypted with the buyer’s public key
//metaDataIdEncWithSeller: meta data is encrypted with the seller’s public key
//sellerPassword: seller password
metaDataIdEncWithBuyer, err = accounts.GetAMInstance().ReEncrypt(
metaDataIdEncWithSeller,
seller.Account.Address,
buyerAddr.String(),
clientPassword,
)
if err != nil {
fmt.Println("failed to ReEncrypt meta data id with buyer's public key")
return false
}
SubmitMetaDataIdEncWithBuyer(txId)
return true
}
func SubmitMetaDataIdEncWithBuyer(txId *big.Int) {
//the buyer needs to monitor to the ReadyForDownload event
txParam := chainoperations.TransactParams{
From: common.HexToAddress(seller.Account.Address),
Password: sellerPassword,
}
err := cif.SubmitMetaDataIdEncWithBuyer(
&txParam,
txId,
metaDataIdEncWithBuyer)
if err != nil {
fmt.Println("failed to SubmitMetaDataIdEncWithBuyer, error:", err)
}
}
func onReadyForDownload(event events.Event) bool {
metaDataIdEncWithBuyer = event.Data.Get("metaDataIdEncBuyer").([]byte)
//buyer to decrypt metaDataIdEncWithBuyer,get original meta data id, download
metaDataId, err := accounts.GetAMInstance().Decrypt(
metaDataIdEncWithBuyer,
buyer.Account.Address,
buyerPassword)
if err != nil {
fmt.Println("failed to decrypt meta data id with buyer's private key", err)
return false
}
return true
}
func ConfirmDataTruth(txId *big.Int) {
buyer.SubscribeEvent("TransactionClose", onClose)
txParam := chainoperations.TransactParams{
From: common.HexToAddress(buyer.Account.Address),
Password: buyerPassword,
}
//txId: transaction ID
err := cif.ConfirmDataTruth(
&txParam,
txId,
true)
if err != nil {
fmt.Println("failed to ConfirmDataTruth, error:", err)
}
}
func onClose(event events.Event) bool {
fmt.Println("onClose:", event)
return true
}