From 311df942e4cc7e2e75116691ce7c10b8a50b34f2 Mon Sep 17 00:00:00 2001 From: AstaFrode Date: Mon, 5 Jun 2023 17:15:57 +0800 Subject: [PATCH] Base gen (#64) * update CharacterName * update sdk * update examples * update readme --- README.md | 63 ++++++++--------------- chain/audit.go | 10 +++- chain/chain.go | 39 ++++++--------- chain/deoss.go | 2 +- chain/file.go | 9 ++-- chain/role.go | 113 +----------------------------------------- chain/sminer.go | 22 ++++---- config/config.go | 19 ++++--- core/sdk/sdk.go | 89 ++++++++++++++++++--------------- core/utils/account.go | 22 -------- examples.go | 28 +++++------ sdk.go | 19 ++++--- 12 files changed, 146 insertions(+), 289 deletions(-) diff --git a/README.md b/README.md index f8c0559..13c41d5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ -The go sdk implementation of the CESS network, which provides RPC calls, status queries, and access to the p2p storage network of the CESS chain. +The go sdk implementation of the CESS network, which provides RPC calls, status queries, block transactions and other functions. ## Reporting a Vulnerability If you find out any vulnerability, Please send an email to frode@cess.one, we are happy to communicate with you. @@ -16,69 +16,50 @@ To get the package use the standard: ``` go get -u "github.com/CESSProject/sdk-go" ``` -Using Go modules is recommended. ## Documentation & Examples Please refer to https://pkg.go.dev/github.com/CESSProject/sdk-go ## Usage -Usually, you only care about how to access your data in the CESS network, you need to build such a web service yourself, this sdk will help you quickly realize data access. +Usually, you only care about how to access your data in the CESS network, you need to build such a web service yourself, this sdk will help you quickly realize data access.Note that the [p2p-go library](https://github.com/CESSProject/p2p-go) needs to be used to complete the data transmission. + #### Create an sdk client instance -The following is an example of creating an sdk client: +To create an sdk client, you need to provide some configuration information: your rpc address (if not, use the rpc address disclosed by CESS), your wallet private key, and transaction timeout. Please refer to the following examples: ``` cli, err := New( - config.DefaultName, - ConnectRpcAddrs([]string{""}), - ListenPort(15000), - Workspace("/"), - Mnemonic("xxx xxx ... xxx"), - TransactionTimeout(time.Duration(time.Second*10)), + config.CharacterName_Client, + ConnectRpcAddrs([]string{"wss://testnet-rpc0.cess.cloud/ws/", "wss://testnet-rpc1.cess.cloud/ws/"}), + Mnemonic("xxx xxx ... xxx"), + TransactionTimeout(time.Duration(time.Second*10)), ) ``` -Creating a client requires you to configure some information, you can refer to the following configuration files: -``` -# The rpc endpoint of the chain node -Rpc: - - "ws://127.0.0.1:9948/" - - "wss://testnet-rpc0.cess.cloud/ws/" - - "wss://testnet-rpc1.cess.cloud/ws/" -# Account mnemonic -Mnemonic: "xxx xxx xxx" -# Service workspace -Workspace: / -# Service running address -Address: "127.0.0.1" -# P2P communication port -P2P_Port: 8088 -# Service listening port -HTTP_Port: 15000 -``` -#### Register as an oss role -Call the Register method to register. Note that the first parameter specifies that the role you register is oss, and its value can be any one of "oss","OSS","Deoss","DEOSS". +#### Register as a deoss role +Call the Register method to register. Note that the first parameter specifies that the role you register is deoss, If there is no error, you can view the transaction details through the returned transaction hash. ``` -txhash, err := cli.Register("oss", "", 0) +txhash, _, err := cli.Register(cli.GetCharacterName(), cli.GetSignatureAccPulickey(), "", 0) ``` -#### Process your documents according to the specifications of CESS +#### Process data according to the specifications of CESS Call the ProcessingData method to process your file. You need to specify the file path. The method returns a segment list and the unique identifier hash of the file in the CESS network. ``` segmentInfo, roothash, err := cli.ProcessingData(filepath) ``` -#### Store your files -Call the PutFile method to store your files. You need to specify a bucket to store the files. CESS will automatically create the bucket for you, provided that the name of the bucket is legal. You can call the CheckBucketName method in advance to check whether the name of the bucket meets the requirements. -After the storage is successful, it will return `count`. The `count` indicates the number of times your file is stored. A file can only be stored up to 5 times. If your file is not stored successfully after 5 times, you need to upload your file again. +#### Create storage order +Before storing data, you also need to create a data storage order, and you need to fill in the roothash and segmentInfo obtained in the previous step, as well as the user account for uploading data, data name, and bucket name. ``` -count, err := cli.PutFile(publickey, segmentInfo, roothash, filename, buckname) +err := cli.GenerateStorageOrder(roothash, segmentInfo, owner, filename, bucketname) ``` -#### Download file -Call the GetFile method to download the file you want, and this method will save the file you downloaded under the roothash name in the directory you specify. -``` -filepath, err := n.Cli.GetFile(roothash, dir) -``` +#### Store data to storage nodes +After creating the storage order, wait for one block to find the storage node information allocated in the order. The next step is to store the data to the storage node through the `WriteFileAction` method in the [p2p-go library](https://github.com/CESSProject/p2p-go). + +After the storage node receives the data, it will automatically report this action. When all the storage nodes in the storage order have all reported, the data is considered to be stored successfully. As long as there is a storage node that does not report, it is regarded as a storage failure. After the timeout period in the order is exceeded, the storage nodes in the order will be reassigned randomly to start a new round of storage. You need to monitor this storage order, and re-give the data block to the newly allocated storage node until the data storage is successful. The `count` in the storage order indicates the number of times your data has been redistributed. An order can redistribute storage up to 5 times. If your data is still not successfully stored after 5 times, you need to re-upload your data. + +#### Fetch your data +Call the `ReadFileAction` method in the [p2p-go library](https://github.com/CESSProject/p2p-go) to download all data blocks, and then restore the original data through the `ReedSolomon_Restore` method. ## License Licensed under [Apache 2.0](https://github.com/CESSProject/sdk-go/blob/main/LICENSE) diff --git a/chain/audit.go b/chain/audit.go index 3e84d39..3cca5e4 100644 --- a/chain/audit.go +++ b/chain/audit.go @@ -20,6 +20,14 @@ import ( ) func (c *ChainSDK) QueryAssignedProof() ([][]pattern.ProofAssignmentInfo, error) { + defer func() { + if err := recover(); err != nil { + log.Println(utils.RecoverError(err)) + } + }() + if !c.GetChainState() { + return nil, pattern.ERR_RPC_CONNECTION + } var list [][]pattern.ProofAssignmentInfo key := createPrefixedKey(pattern.AUDIT, pattern.UNVERIFYPROOF) keys, err := c.api.RPC.State.GetKeysLatest(key) @@ -47,7 +55,7 @@ func (c *ChainSDK) QueryAssignedProof() ([][]pattern.ProofAssignmentInfo, error) func (c *ChainSDK) QueryTeeAssignedProof(puk []byte) ([]pattern.ProofAssignmentInfo, error) { defer func() { if err := recover(); err != nil { - log.Panicln(utils.RecoverError(err)) + log.Println(utils.RecoverError(err)) } }() var data []pattern.ProofAssignmentInfo diff --git a/chain/chain.go b/chain/chain.go index e662b1d..53b42f5 100644 --- a/chain/chain.go +++ b/chain/chain.go @@ -8,7 +8,6 @@ package chain import ( - "fmt" "io" "log" "os" @@ -37,22 +36,18 @@ type ChainSDK struct { rpcAddr []string timeForBlockOut time.Duration tokenSymbol string - stakingAcc string + signatureAcc string name string } var _ sdk.SDK = (*ChainSDK)(nil) -func NewChainSDK(rpcs []string, name, mnemonic string, t time.Duration) (*ChainSDK, error) { +func NewChainSDK(name string, rpcs []string, mnemonic string, t time.Duration) (*ChainSDK, error) { var ( err error chainSDK = &ChainSDK{} ) - if name == "" { - return nil, fmt.Errorf("empty name") - } - defer log.SetOutput(os.Stdout) log.SetOutput(io.Discard) @@ -88,7 +83,7 @@ func NewChainSDK(rpcs []string, name, mnemonic string, t time.Duration) (*ChainS if err != nil { return nil, err } - chainSDK.stakingAcc, err = utils.EncodePublicKeyAsCessAccount(chainSDK.keyring.PublicKey) + chainSDK.signatureAcc, err = utils.EncodePublicKeyAsCessAccount(chainSDK.keyring.PublicKey) if err != nil { return nil, err } @@ -133,30 +128,16 @@ func (c *ChainSDK) GetChainState() bool { return c.chainState.Load() } -func (c *ChainSDK) NewAccountId(pubkey []byte) types.AccountID { - acc, _ := types.NewAccountID(pubkey) - return *acc -} - func (c *ChainSDK) GetSignatureAcc() string { - acc, _ := utils.EncodePublicKeyAsCessAccount(c.keyring.PublicKey) - return acc + return c.signatureAcc } func (c *ChainSDK) GetKeyEvents() types.StorageKey { return c.keyEvents } -// ExtractAccountPublickey -func (c *ChainSDK) ExtractAccountPuk(account string) ([]byte, error) { - if account != "" { - return utils.ParsingPublickey(account) - } - return c.keyring.PublicKey, nil -} - -func (c *ChainSDK) GetSignatureURIs() string { - return c.keyring.URI +func (c *ChainSDK) GetSignatureAccPulickey() []byte { + return c.keyring.PublicKey } func (c *ChainSDK) GetSubstrateAPI() *gsrpc.SubstrateAPI { @@ -171,10 +152,18 @@ func (c *ChainSDK) GetTokenSymbol() string { return c.tokenSymbol } +func (c *ChainSDK) GetCharacterName() string { + return c.name +} + func (c *ChainSDK) Sign(msg []byte) ([]byte, error) { return signature.Sign(msg, c.keyring.URI) } +func (c *ChainSDK) Verify(msg []byte, sig []byte) (bool, error) { + return signature.Verify(msg, sig, c.keyring.URI) +} + func reconnectChainSDK(rpcAddr []string) (*gsrpc.SubstrateAPI, error) { var err error var api *gsrpc.SubstrateAPI diff --git a/chain/deoss.go b/chain/deoss.go index c4183db..62a8735 100644 --- a/chain/deoss.go +++ b/chain/deoss.go @@ -21,7 +21,7 @@ import ( func (c *ChainSDK) QueryDeoss(pubkey []byte) ([]byte, error) { defer func() { if err := recover(); err != nil { - log.Panicln(utils.RecoverError(err)) + log.Println(utils.RecoverError(err)) } }() var data pattern.PeerId diff --git a/chain/file.go b/chain/file.go index aaf7cc6..dd4f785 100644 --- a/chain/file.go +++ b/chain/file.go @@ -37,7 +37,7 @@ func (c *ChainSDK) ProcessingData(path string) ([]pattern.SegmentDataInfo, strin return nil, "", err } if fstat.IsDir() { - return nil, "", errors.New("Not a file") + return nil, "", errors.New("not a file") } baseDir := filepath.Dir(path) @@ -116,7 +116,7 @@ func (c *ChainSDK) ProcessingData(path string) ([]pattern.SegmentDataInfo, strin return segment, hex.EncodeToString(hTree.MerkleRoot()), err } -func (c *ChainSDK) GenerateStorageOrder(roothash string, segment []pattern.SegmentDataInfo, owner []byte, filename, buckname string) error { +func (c *ChainSDK) GenerateStorageOrder(roothash string, segment []pattern.SegmentDataInfo, owner []byte, filename, buckname string) (string, error) { var err error var segmentList = make([]pattern.SegmentList, len(segment)) var user pattern.UserBrief @@ -135,13 +135,12 @@ func (c *ChainSDK) GenerateStorageOrder(roothash string, segment []pattern.Segme } acc, err := types.NewAccountID(owner) if err != nil { - return err + return "", err } user.User = *acc user.BucketName = types.NewBytes([]byte(buckname)) user.FileName = types.NewBytes([]byte(filename)) - _, err = c.UploadDeclaration(roothash, segmentList, user) - return err + return c.UploadDeclaration(roothash, segmentList, user) } func ExtractSegmenthash(segment []pattern.SegmentDataInfo) []string { diff --git a/chain/role.go b/chain/role.go index e975b0f..52a0686 100644 --- a/chain/role.go +++ b/chain/role.go @@ -95,7 +95,7 @@ func (c *ChainSDK) Register(role string, puk []byte, earnings string, pledge uin if err != nil { return txhash, acc, err } - txhash, err = c.updateIncomeAcc(key, puk) + txhash, err = c.updateEarningsAcc(key, puk) return txhash, earnings, err } } @@ -194,117 +194,6 @@ func (c *ChainSDK) Register(role string, puk []byte, earnings string, pledge uin } } -func (c *ChainSDK) UpdateAddress(role, multiaddr string) (string, error) { - c.lock.Lock() - defer func() { - c.lock.Unlock() - if err := recover(); err != nil { - log.Println(utils.RecoverError(err)) - } - }() - - var ( - err error - txhash string - call types.Call - accountInfo types.AccountInfo - ) - - if !c.GetChainState() { - return txhash, pattern.ERR_RPC_CONNECTION - } - - switch role { - case pattern.Role_OSS, pattern.Role_DEOSS, "deoss", "oss", "Deoss", "DeOSS": - call, err = types.NewCall(c.metadata, pattern.TX_OSS_UPDATE, types.NewBytes([]byte(multiaddr))) - if err != nil { - return txhash, errors.Wrap(err, "[NewCall]") - } - case pattern.Role_BUCKET, "SMINER", "bucket", "Bucket", "Sminer", "sminer": - call, err = types.NewCall(c.metadata, pattern.TX_SMINER_UPDATEPEERID, types.NewBytes([]byte(multiaddr))) - if err != nil { - return txhash, errors.Wrap(err, "[NewCall]") - } - default: - return "", fmt.Errorf("Invalid role name") - } - - key, err := types.CreateStorageKey(c.metadata, pattern.SYSTEM, pattern.ACCOUNT, c.keyring.PublicKey) - if err != nil { - return txhash, errors.Wrap(err, "[CreateStorageKey]") - } - - ok, err := c.api.RPC.State.GetStorageLatest(key, &accountInfo) - if err != nil { - return txhash, errors.Wrap(err, "[GetStorageLatest]") - } - if !ok { - return txhash, pattern.ERR_RPC_EMPTY_VALUE - } - - o := types.SignatureOptions{ - BlockHash: c.genesisHash, - Era: types.ExtrinsicEra{IsMortalEra: false}, - GenesisHash: c.genesisHash, - Nonce: types.NewUCompactFromUInt(uint64(accountInfo.Nonce)), - SpecVersion: c.runtimeVersion.SpecVersion, - Tip: types.NewUCompactFromUInt(0), - TransactionVersion: c.runtimeVersion.TransactionVersion, - } - - ext := types.NewExtrinsic(call) - - // Sign the transaction - err = ext.Sign(c.keyring, o) - if err != nil { - return txhash, errors.Wrap(err, "[Sign]") - } - - // Do the transfer and track the actual status - sub, err := c.api.RPC.Author.SubmitAndWatchExtrinsic(ext) - if err != nil { - return txhash, errors.Wrap(err, "[SubmitAndWatchExtrinsic]") - } - defer sub.Unsubscribe() - - timeout := time.NewTimer(c.timeForBlockOut) - defer timeout.Stop() - - for { - select { - case status := <-sub.Chan(): - if status.IsInBlock { - events := event.EventRecords{} - txhash, _ = codec.EncodeToHex(status.AsInBlock) - h, err := c.api.RPC.State.GetStorageRaw(c.keyEvents, status.AsInBlock) - if err != nil { - return txhash, errors.Wrap(err, "[GetStorageRaw]") - } - err = types.EventRecordsRaw(*h).DecodeEventRecords(c.metadata, &events) - if err != nil { - return txhash, nil - } - switch role { - case pattern.Role_OSS, pattern.Role_DEOSS, "deoss", "oss", "Deoss", "DeOSS": - if len(events.Oss_OssUpdate) > 0 { - return txhash, nil - } - case pattern.Role_BUCKET, "SMINER", "bucket", "Bucket", "Sminer", "sminer": - if len(events.Sminer_UpdataIp) > 0 { - return txhash, nil - } - default: - return txhash, errors.New(pattern.ERR_Failed) - } - } - case err = <-sub.Err(): - return txhash, errors.Wrap(err, "[sub]") - case <-timeout.C: - return txhash, pattern.ERR_RPC_TIMEOUT - } - } -} - func (c *ChainSDK) updateAddress(key types.StorageKey, name string, peerid pattern.PeerId) (string, error) { var ( err error diff --git a/chain/sminer.go b/chain/sminer.go index d8838f3..926e86d 100644 --- a/chain/sminer.go +++ b/chain/sminer.go @@ -80,7 +80,7 @@ func (c *ChainSDK) QuerySminerList() ([]types.AccountID, error) { } // QueryMinerRewards -func (c *ChainSDK) QueryMinerRewards(puk []byte) (pattern.MinerReward, error) { +func (c *ChainSDK) QueryStorageNodeReward(puk []byte) (pattern.MinerReward, error) { defer func() { if err := recover(); err != nil { log.Println(utils.RecoverError(err)) @@ -108,9 +108,9 @@ func (c *ChainSDK) QueryMinerRewards(puk []byte) (pattern.MinerReward, error) { return data, nil } -func (c *ChainSDK) QuaryRewards(puk []byte) (pattern.RewardsType, error) { +func (c *ChainSDK) QuaryStorageNodeRewardInfo(puk []byte) (pattern.RewardsType, error) { var reward pattern.RewardsType - rewards, err := c.QueryMinerRewards(puk) + rewards, err := c.QueryStorageNodeReward(puk) if err != nil { return reward, err } @@ -122,7 +122,7 @@ func (c *ChainSDK) QuaryRewards(puk []byte) (pattern.RewardsType, error) { return reward, nil } -func (c *ChainSDK) UpdateIncomeAcc(puk []byte) (string, error) { +func (c *ChainSDK) UpdateEarningsAcc(puk []byte) (string, error) { c.lock.Lock() defer func() { c.lock.Unlock() @@ -215,7 +215,7 @@ func (c *ChainSDK) UpdateIncomeAcc(puk []byte) (string, error) { } } -func (c *ChainSDK) updateIncomeAcc(key types.StorageKey, puk []byte) (string, error) { +func (c *ChainSDK) updateEarningsAcc(key types.StorageKey, puk []byte) (string, error) { var ( txhash string accountInfo types.AccountInfo @@ -291,16 +291,16 @@ func (c *ChainSDK) updateIncomeAcc(key types.StorageKey, puk []byte) (string, er } } -func (c *ChainSDK) UpdateIncomeAccount(income string) (string, error) { - puk, err := utils.ParsingPublickey(income) +func (c *ChainSDK) UpdateEarningsAccount(earnings string) (string, error) { + puk, err := utils.ParsingPublickey(earnings) if err != nil { return "", err } - return c.UpdateIncomeAcc(puk) + return c.UpdateEarningsAcc(puk) } // Storage miners increase deposit function -func (c *ChainSDK) IncreaseStakes(tokens *big.Int) (string, error) { +func (c *ChainSDK) IncreaseStakingAmount(tokens *big.Int) (string, error) { c.lock.Lock() defer func() { c.lock.Unlock() @@ -388,12 +388,12 @@ func (c *ChainSDK) IncreaseStakes(tokens *big.Int) (string, error) { } } -func (c *ChainSDK) IncreaseSminerStakes(token string) (string, error) { +func (c *ChainSDK) IncreaseStorageNodeStakingAmount(token string) (string, error) { tokens, ok := new(big.Int).SetString(token+pattern.TokenPrecision_CESS, 10) if !ok { return "", fmt.Errorf("Invalid tokens: %s", token) } - return c.IncreaseStakes(tokens) + return c.IncreaseStakingAmount(tokens) } // ClaimRewards diff --git a/config/config.go b/config/config.go index 89a67eb..9320305 100644 --- a/config/config.go +++ b/config/config.go @@ -8,6 +8,7 @@ package config import ( + "fmt" "time" "github.com/CESSProject/sdk-go/chain" @@ -25,17 +26,23 @@ type Config struct { // Option is a client config option that can be given to the client constructor type Option func(cfg *Config) error -const DefaultName = "SDK" +// SDK available character name +const ( + CharacterName_Client = "client" + CharacterName_Bucket = "bucket" + CharacterName_Deoss = "deoss" +) // NewSDK constructs a new client from the Config. // // This function consumes the config. Do not reuse it (really!). -func (cfg *Config) NewSDK(name string) (sdk.SDK, error) { - var serviceName = DefaultName - if name != "" { - serviceName = name +func (cfg *Config) NewSDK(characterName string) (sdk.SDK, error) { + if characterName != CharacterName_Bucket && + characterName != CharacterName_Deoss && + characterName != CharacterName_Client { + return nil, fmt.Errorf("invalid character name") } - return chain.NewChainSDK(cfg.Rpc, serviceName, cfg.Mnemonic, cfg.Timeout) + return chain.NewChainSDK(characterName, cfg.Rpc, cfg.Mnemonic, cfg.Timeout) } // Apply applies the given options to the config, returning the first error diff --git a/core/sdk/sdk.go b/core/sdk/sdk.go index 03e8889..f68952f 100644 --- a/core/sdk/sdk.go +++ b/core/sdk/sdk.go @@ -27,19 +27,22 @@ type SDK interface { QueryDeoss(pubkey []byte) ([]byte, error) // QuaryAuthorizedAcc queries the account authorized by puk. + // QuaryAuthorizedAccount query account in string form. QuaryAuthorizedAcc(puk []byte) (types.AccountID, error) QuaryAuthorizedAccount(puk []byte) (string, error) + + // CheckSpaceUsageAuthorization checks if the puk is authorized to itself CheckSpaceUsageAuthorization(puk []byte) (bool, error) // QueryBucketInfo queries the information of the "bucketname" bucket of the puk. QueryBucketInfo(puk []byte, bucketname string) (pattern.BucketInfo, error) // QueryBucketList queries all buckets of the puk. - // QueryAllBucketName + // QueryAllBucketName queries all bucket names as strings. QueryBucketList(puk []byte) ([]types.Bytes, error) QueryAllBucketName(puk []byte) ([]string, error) - // QueryFileMetaInfo queries the metadata of the roothash file. + // QueryFileMetadata queries the metadata of the roothash file. QueryFileMetadata(roothash string) (pattern.FileMetadata, error) // QueryStorageMiner queries storage node information. @@ -67,7 +70,9 @@ type SDK interface { // QueryChallengeSnapshot query challenge information snapshot. QueryChallengeSnapshot() (pattern.ChallengeSnapShot, error) QueryChallengeSt() (pattern.ChallengeSnapshot, error) - QueryChallenge(pubkey []byte) (pattern.ChallengeInfo, error) + + // QueryChallenge queries puk's challenge information. + QueryChallenge(puk []byte) (pattern.ChallengeInfo, error) // QueryTeePodr2Puk queries the public key of the TEE. QueryTeePodr2Puk() ([]byte, error) @@ -79,25 +84,22 @@ type SDK interface { QueryTeeInfoList() ([]pattern.TeeWorkerInfo, error) QueryTeeWorkerList() ([]pattern.TeeWorkerSt, error) - // + // QueryAssignedProof queries all assigned proof information. QueryAssignedProof() ([][]pattern.ProofAssignmentInfo, error) - // + // ProofAssignmentInfo queries the proof information assigned to puk. QueryTeeAssignedProof(puk []byte) ([]pattern.ProofAssignmentInfo, error) - // - QueryMinerRewards(puk []byte) (pattern.MinerReward, error) - QuaryRewards(puk []byte) (pattern.RewardsType, error) + // QueryStorageNodeReward queries reward information for puk account. + QueryStorageNodeReward(puk []byte) (pattern.MinerReward, error) + QuaryStorageNodeRewardInfo(puk []byte) (pattern.RewardsType, error) - // Register is used to register OSS or BUCKET roles. + // Register is used to register oss or bucket roles. Register(role string, puk []byte, earnings string, pledge uint64) (string, string, error) - // UpdateAddress updates the address of oss or sminer. - UpdateAddress(role, multiaddr string) (string, error) - - // UpdateIncomeAcc update income account. - UpdateIncomeAcc(puk []byte) (string, error) - UpdateIncomeAccount(income string) (string, error) + // UpdateEarningsAcc update earnings account. + UpdateEarningsAcc(puk []byte) (string, error) + UpdateEarningsAccount(earnings string) (string, error) // CreateBucket creates a bucket for puk. CreateBucket(puk []byte, bucketname string) (string, error) @@ -111,6 +113,12 @@ type SDK interface { // UploadDeclaration creates a storage order. UploadDeclaration(roothash string, dealinfo []pattern.SegmentList, user pattern.UserBrief) (string, error) + // GenerateStorageOrder for generating storage orders + GenerateStorageOrder(roothash string, segment []pattern.SegmentDataInfo, owner []byte, filename, buckname string) (string, error) + + // ProcessingData is used to process the uploaded data. + ProcessingData(path string) ([]pattern.SegmentDataInfo, string, error) + // SubmitIdleMetadata Submit idle file metadata. SubmitIdleMetadata(teeAcc []byte, idlefiles []pattern.IdleMetadata) (string, error) SubmitIdleFile(teeAcc []byte, idlefiles []pattern.IdleFileMeta) (string, error) @@ -123,65 +131,64 @@ type SDK interface { ReplaceIdleFiles(roothash []pattern.FileHash) (string, []pattern.FileHash, error) ReplaceFile(roothash []string) (string, []string, error) - // IncreaseStakes increase stakes. - IncreaseStakes(tokens *big.Int) (string, error) - IncreaseSminerStakes(token string) (string, error) + // IncreaseStakingAmount increase staking amount. + IncreaseStakingAmount(tokens *big.Int) (string, error) + IncreaseStorageNodeStakingAmount(token string) (string, error) // Exit exit the cess network. Exit(role string) (string, error) - // ClaimRewards is used to claim rewards + // ClaimRewards is used to claim rewards. ClaimRewards() (string, error) - // Withdraw is used to withdraw staking + // Withdraw is used to withdraw staking. Withdraw() (string, error) - // + // ReportProof is used to report proof data. ReportProof(idlesigma, servicesigma string) (string, error) - // ExtractAccountPuk extracts the public key of the account, - // and returns its own public key if the account is empty. - ExtractAccountPuk(account string) ([]byte, error) - // GetSignatureAcc returns the signature account. GetSignatureAcc() string - // GetSubstrateAPI returns Substrate API + // GetSignatureAccPulickey returns the signature account public key. + GetSignatureAccPulickey() []byte + + // GetSubstrateAPI returns Substrate API. GetSubstrateAPI() *gsrpc.SubstrateAPI - // GetChainState returns chain node state + // GetChainState returns chain node state. GetChainState() bool - // + // SetChainState sets the state of the chain node. SetChainState(state bool) - // + // GetCharacterName returns the character name. + GetCharacterName() string + + // Reconnect for reconnecting chains. Reconnect() error - // + // GetMetadata returns the metadata of the chain. GetMetadata() *types.Metadata - // + // GetKeyEvents returns the events storage key. GetKeyEvents() types.StorageKey - // + // SysProperties returns the system properties. SysProperties() (pattern.SysProperties, error) - // + // SyncState returns the system sync state. SyncState() (pattern.SysSyncState, error) - // + // SysVersion returns the system version. SysVersion() (string, error) - // + // NetListening returns whether the current node is listening. NetListening() (bool, error) - // + // Sign returns the signature of the msg with the private key of the signing account. Sign(msg []byte) ([]byte, error) - // - ProcessingData(path string) ([]pattern.SegmentDataInfo, string, error) - - // - GenerateStorageOrder(roothash string, segment []pattern.SegmentDataInfo, owner []byte, filename, buckname string) error + // Verify the signature of the msg with the public key of the signing account. + Verify(msg []byte, sig []byte) (bool, error) } diff --git a/core/utils/account.go b/core/utils/account.go index de2d622..27d15b5 100644 --- a/core/utils/account.go +++ b/core/utils/account.go @@ -9,7 +9,6 @@ package utils import ( "errors" - "fmt" "github.com/btcsuite/btcutil/base58" "golang.org/x/crypto/blake2b" @@ -42,27 +41,6 @@ func ParsingPublickey(address string) ([]byte, error) { } } -// func DecodePublicKeyOfSubstrateAccount(address string) ([]byte, error) { -// err := VerityAddress(address, SubstratePrefix) -// if err != nil { -// return nil, errors.New("Invalid account") -// } -// data := base58.Decode(address) -// if len(data) != (34 + len(SubstratePrefix)) { -// return nil, errors.New("Public key decoding failed") -// } -// return data[len(SubstratePrefix) : len(data)-2], nil -// } - -func PubBytesToString(b []byte) string { - s := "" - for i := 0; i < len(b); i++ { - tmp := fmt.Sprintf("%#02x", b[i]) - s += tmp[2:] - } - return s -} - func EncodePublicKeyAsSubstrateAccount(publicKey []byte) (string, error) { if len(publicKey) != 32 { return "", errors.New("Invalid public key") diff --git a/examples.go b/examples.go index 80f88f1..4c7f53e 100644 --- a/examples.go +++ b/examples.go @@ -16,8 +16,8 @@ import ( func Example_newClient() { _, err := New( - config.DefaultName, - ConnectRpcAddrs([]string{""}), + config.CharacterName_Client, + ConnectRpcAddrs([]string{"wss://testnet-rpc0.cess.cloud/ws/", "wss://testnet-rpc1.cess.cloud/ws/"}), Mnemonic("xxx xxx ... xxx"), TransactionTimeout(time.Duration(time.Second*10)), ) @@ -26,36 +26,36 @@ func Example_newClient() { } } -func Example_registerOss() { +func Example_RegisterDeoss() { cli, err := New( - "oss", - ConnectRpcAddrs([]string{""}), - Mnemonic(""), + config.CharacterName_Deoss, + ConnectRpcAddrs([]string{"wss://testnet-rpc0.cess.cloud/ws/", "wss://testnet-rpc1.cess.cloud/ws/"}), + Mnemonic("xxx xxx ... xxx"), TransactionTimeout(time.Duration(time.Second*10)), ) if err != nil { panic(err) } - txhash, _, err := cli.Register("oss", nil, "", 0) + txhash, _, err := cli.Register(cli.GetCharacterName(), cli.GetSignatureAccPulickey(), "", 0) if err != nil { panic(err) } - fmt.Printf("OSS registration successful, transaction hash is %s\n", txhash) + fmt.Printf("Deoss registration successful, transaction hash is %s\n", txhash) } -func Example_registerMiner() { +func Example_RegisterStorageNode() { cli, err := New( - "bucket", - ConnectRpcAddrs([]string{""}), - Mnemonic(""), + config.CharacterName_Bucket, + ConnectRpcAddrs([]string{"wss://testnet-rpc0.cess.cloud/ws/", "wss://testnet-rpc1.cess.cloud/ws/"}), + Mnemonic("xxx xxx ... xxx"), TransactionTimeout(time.Duration(time.Second*10)), ) if err != nil { panic(err) } - txhash, _, err := cli.Register("bucket", nil, "cXxxx...xxx", 100000) + txhash, _, err := cli.Register(cli.GetCharacterName(), cli.GetSignatureAccPulickey(), "cXxxx...xxx", 100000) if err != nil { panic(err) } - fmt.Printf("Miner registration successful, transaction hash is %s\n", txhash) + fmt.Printf("Storage node registration successful, transaction hash is %s\n", txhash) } diff --git a/sdk.go b/sdk.go index 66d2b76..896a263 100644 --- a/sdk.go +++ b/sdk.go @@ -12,25 +12,24 @@ import ( "github.com/CESSProject/sdk-go/core/sdk" ) -// Config describes a set of settings for a client. +// Config describes a set of settings for the sdk. type Config = config.Config // Option is a client config option that can be given to the client constructor type Option = config.Option -// New constructs a new client with the given options, falling back on +// New constructs a new sdk client with the given options, falling back on // reasonable defaults. The defaults are: // -// - If no transport and listen addresses are provided, the node listens to -// the default addresses "/ip4/0.0.0.0/tcp/15000"; -// -// - If no Rpc address is provided, the client uses the default address +// - If no rpc address is provided, the sdk client uses the default address // "wss://testnet-rpc0.cess.cloud/ws/"" or "wss://testnet-rpc1.cess.cloud/ws/"; // -// - If no working directory is provided, the client uses the current -// directory as the working directory; -func New(name string, opts ...Option) (sdk.SDK, error) { - return NewWithoutDefaults(name, append(opts, FallbackDefaults)...) +// - If no transaction timeout is provided, the sdk client uses the default +// timeout: time.Duration(time.Second * 6) +// +// - The characterName available in the sdk are: client, bucket, deoss +func New(characterName string, opts ...Option) (sdk.SDK, error) { + return NewWithoutDefaults(characterName, append(opts, FallbackDefaults)...) } // NewWithoutDefaults constructs a new client with the given options but