diff --git a/common/common.go b/common/common.go index dacae18..2c95f72 100644 --- a/common/common.go +++ b/common/common.go @@ -1,5 +1,30 @@ package common +type KeyType int + +const ( + ECDSA KeyType = 0 + Ed25519 KeyType = 1 + SoftGMAlg KeyType = 2 +) + + +/*func (keyType KeyType) String() string { + switch keyType { + case secp256k1: + return "secp256k1" + case Ed25519: + return "Ed25519" + default: + return "unknown key type" + } +}*/ + +/*func (keyType KeyType) MarshalText() ([]byte, error) { + + return []byte(keyType.String()), nil +}*/ + // Auth is the type with ws connection infomations type Auth struct { Address string @@ -10,15 +35,22 @@ type Auth struct { //IRequest define interface for request type IRequest interface { GetID() int64 + SetSchemaID(schemaID string) *RequestBase } //RequestBase contains fields that all requests will have type RequestBase struct { - Command string `json:"command"` - ID int64 `json:"id,omitempty"` + Command string `json:"command"` + ID int64 `json:"id,omitempty"` + SchemaID string `json:"schema_id"` } // GetID return id for request func (r *RequestBase) GetID() int64 { return r.ID } + +func (r *RequestBase) SetSchemaID(schemaID string) *RequestBase { + r.SchemaID = schemaID + return r +} diff --git a/core/chainsql.go b/core/chainsql.go index 34a4aa3..0f60a14 100644 --- a/core/chainsql.go +++ b/core/chainsql.go @@ -1,19 +1,32 @@ package core import ( - "log" + "encoding/hex" + "encoding/json" + "fmt" + "strings" "github.com/ChainSQL/go-chainsql-api/crypto" . "github.com/ChainSQL/go-chainsql-api/data" "github.com/ChainSQL/go-chainsql-api/export" "github.com/ChainSQL/go-chainsql-api/net" "github.com/ChainSQL/go-chainsql-api/util" + "github.com/buger/jsonparser" ) // Chainsql is the interface struct for this package type Chainsql struct { client *net.Client SubmitBase + op *ChainsqlTxInfo +} + +//TxInfo is the opearting details +type ChainsqlTxInfo struct { + //Signer Signer + Raw string + TxType TransactionType + Query []interface{} } type TableGetSqlJSON struct { @@ -26,6 +39,9 @@ type TableGetSqlJSON struct { func NewChainsql() *Chainsql { chainsql := &Chainsql{ client: net.NewClient(), + op: &ChainsqlTxInfo{ + Query: make([]interface{}, 0), + }, } chainsql.SubmitBase.client = chainsql.client chainsql.SubmitBase.IPrepare = chainsql @@ -47,22 +63,14 @@ func (c *Chainsql) Use(owner string) { c.client.Auth.Owner = owner } -// PrepareTx prepare tx json for submit -func (c *Chainsql) PrepareTx() (Signer, error) { - - log.Println("Chainsql prepareTx") - tx := &TableListSet{} - return tx, nil -} - //Table create a new table object func (c *Chainsql) Table(name string) *Table { return NewTable(name, c.client) } //Connect is used to create a websocket connection -func (c *Chainsql) Connect(url string) error { - return c.client.Connect(url) +func (c *Chainsql) Connect(url, tlsRootCertPath, tlsClientCertPath, tlsClientKeyPath, serverName string) error { + return c.client.Connect(url, tlsRootCertPath, tlsClientCertPath, tlsClientKeyPath, serverName) } // GetLedger request a ledger @@ -82,12 +90,16 @@ func (c *Chainsql) OnLedgerClosed(callback export.Callback) { // "publicKeyHex":"02EA30B2A25844D4AFBAF6020DA9C9FED573AA0058791BFC8642E69888693CF8EA", // "privateKey":"xniMQKhxZTMbfWb8scjRPXa5Zv6HB", // } -func (c *Chainsql) GenerateAccount(args ...string) (string, error) { +/*func (c *Chainsql) GenerateAccount(args ...string) (string, error) { if len(args) == 0 { return crypto.GenerateAccount() } else { return crypto.GenerateAccount(args[0]) } +}*/ + +func (c *Chainsql) GenerateAddress(options string) (string, error) { + return crypto.GenerateAddress(options) } //SignPlainData sign a plain text and return the signature @@ -127,6 +139,7 @@ func (c *Chainsql) IsConnected() bool { func (c *Chainsql) Disconnect() { if c.client.GetWebocketManager() != nil { + c.client.Unsubscribe() c.client.GetWebocketManager().Disconnect() } } @@ -136,32 +149,275 @@ func (c *Chainsql) ValidationCreate() (string, error) { } func (c *Chainsql) GetServerInfo() (string, error) { - return "", nil + return c.client.GetServerInfo() } func (c *Chainsql) GetAccountInfo(address string) (string, error) { - return crypto.GetAccountInfo(address) + return c.client.GetAccountInfo(address) } -func (c *Chainsql) Pay(accountId string, value string) *Ripple { - r := NewRipple() +func (c *Chainsql) Pay(accountId string, value int64) *Ripple { + r := NewRipple(c.client) return r.Pay(accountId, value) } func (c *Chainsql) CreateSchema(schemaInfo string) *Chainsql { + c.op.TxType = SCHEMA_CREATE + c.op.Raw = schemaInfo + return c +} +func (c *Chainsql) createSchema() (Signer, error) { + var schemaInfo = c.op.Raw + isValid := strings.Contains(schemaInfo, "SchemaName") && strings.Contains(schemaInfo, "WithState") && + strings.Contains(schemaInfo, "Validators") && strings.Contains(schemaInfo, "PeerList") + + if !isValid { + return nil, fmt.Errorf("Invalid schemaInfo parameter") + } + createSchema := &SchemaCreate{TxBase: TxBase{TransactionType: SCHEMA_CREATE}} + var jsonObj CreateSchema + err := json.Unmarshal([]byte(schemaInfo), &jsonObj) + if err != nil { + return nil, err + } + + createSchema.SchemaName = VariableLength(jsonObj.SchemaName) + if strings.Contains(schemaInfo, "SchemaAdmin") { + account, err := NewAccountFromAddress(jsonObj.SchemaAdmin) + if err != nil { + return nil, fmt.Errorf("Invalid schemaInfo parameter: SchemaAdmin") + } + if account != nil { + createSchema.SchemaAdmin = account + } + } + + if jsonObj.WithState { + //继承主链的节点状态 + if strings.Contains(schemaInfo, "AnchorLedgerHash") { + leadgerHash, errHash := NewHash256(jsonObj.AnchorLedgerHash) + if errHash != nil { + return nil, fmt.Errorf("Invalid schemaInfo parameter: AnchorLedgerHash") + } + if leadgerHash != nil { + createSchema.AnchorLedgerHash = leadgerHash + } + } + createSchema.SchemaStrategy = 2 + } else { + // 不继承主链的节点状态 + createSchema.SchemaStrategy = 1 + if strings.Contains(schemaInfo, "AnchorLedgerHash") { + return nil, fmt.Errorf("Field 'AnchorLedgerHash' is unnecessary") + } + } + + validatorSlice := make([]ValidatorFormat, len(jsonObj.Validators)) + for i := 0; i < len(jsonObj.Validators); i++ { + publicKeyHex := jsonObj.Validators[i].Validator.PublicKey + publicKey, _ := hex.DecodeString(publicKeyHex) + validatorSlice[i].Validator.PublicKey = VariableLength(publicKey) + } + createSchema.Validators = validatorSlice + peerSlice := make([]PeerFormat, len(jsonObj.PeerList)) + for i := 0; i < len(jsonObj.PeerList); i++ { + endpoint := jsonObj.PeerList[i].Peer.Endpoint + peerSlice[i].Peer.Endpoint = VariableLength(endpoint) + } + + createSchema.PeerList = peerSlice + var signer Signer = createSchema + return signer, nil +} +func (c *Chainsql) ModifySchema(schemaType string, schemaInfo string) *Chainsql { + c.op.TxType = SCHEMA_MODIFY + c.op.Raw = "{\"SchemaType\": \"" + schemaType + "\", \"SchemaInfo\":" + schemaInfo + "}" return c } -func (c *Chainsql) ModifySchema(schemaInfo string) *Chainsql { +func (c *Chainsql) modifySchema() (Signer, error) { + schemaType, _ := jsonparser.GetString([]byte(c.op.Raw), "SchemaType") + result, _, _, _ := jsonparser.Get([]byte(c.op.Raw), "SchemaInfo") + schemaInfo := string(result) + isValid := strings.Contains(schemaInfo, "SchemaID") && strings.Contains(schemaInfo, "Validators") && strings.Contains(schemaInfo, "PeerList") + if !isValid { + return nil, fmt.Errorf("Invalid schemaInfo parameter") + } + var jsonObj ModifySchema + errUnmarshal := json.Unmarshal([]byte(schemaInfo), &jsonObj) + if errUnmarshal != nil { + return nil, errUnmarshal + } + schemaModify := &SchemaModify{TxBase: TxBase{TransactionType: SCHEMA_MODIFY}} + if schemaType == util.SchemaDel { + schemaModify.OpType = util.OpTypeSchemaDel + } else { + schemaModify.OpType = util.OpTypeSchemaAdd + } + validatorSlice := make([]ValidatorFormat, len(jsonObj.Validators)) + for i := 0; i < len(jsonObj.Validators); i++ { + publicKeyHex := jsonObj.Validators[i].Validator.PublicKey + publicKey, _ := hex.DecodeString(publicKeyHex) + validatorSlice[i].Validator.PublicKey = VariableLength(publicKey) + } + schemaModify.Validators = validatorSlice + + peerSlice := make([]PeerFormat, len(jsonObj.PeerList)) + for i := 0; i < len(jsonObj.PeerList); i++ { + endpoint := jsonObj.PeerList[i].Peer.Endpoint + peerSlice[i].Peer.Endpoint = VariableLength(endpoint) + } + schemaModify.PeerList = peerSlice + schemaIdHash, errHash := NewHash256(jsonObj.SchemaID) + if errHash != nil { + return nil, errHash + } + if schemaIdHash != nil { + schemaModify.SchemaID = *schemaIdHash + } + //schemaModify.TransactionType = SCHEMA_MODIFY + var signer Signer = schemaModify + return signer, nil +} + +func (c *Chainsql) DeleteSchema(schemaID string) *Chainsql { + c.op.TxType = SCHEMA_DELETE + c.op.Raw = schemaID return c } +func (c *Chainsql) deleteSchema() (Signer, error) { + var schemaID = c.op.Raw + if schemaID == "" { + return nil, fmt.Errorf("Invalid parameter") + } + schemaDelete := &SchemaDelete{TxBase: TxBase{TransactionType: SCHEMA_DELETE}} + schemaIdHash, errHash := NewHash256(schemaID) + if errHash != nil { + return nil, errHash + } + if schemaIdHash != nil { + schemaDelete.SchemaID = *schemaIdHash + } + var signer Signer = schemaDelete + return signer, nil +} + func (c *Chainsql) GetSchemaList(params string) (string, error) { - return "", nil + return c.client.GetSchemaList(params) } -func (c *Chainsql) UpdateSchemaConfig(params string) *Chainsql { - return c +func (c *Chainsql) GetSchemaInfo(schemaID string) (string, error) { + return c.client.GetSchemaInfo(schemaID) +} + +func (c *Chainsql) StopSchema(schemaID string) (string, error) { + return c.client.StopSchema(schemaID) +} + +func (c *Chainsql) StartSchema(schemaID string) (string, error) { + return c.client.StartSchema(schemaID) +} + +func (c *Chainsql) SetSchema(schemaId string) { + if c.client.SchemaID != schemaId { + c.client.Unsubscribe() + c.client.SchemaID = schemaId + c.client.InitSubscription() + } +} +func (c *Chainsql) GetSchemaId(hash string) (string, error) { + response, _ := c.client.GetTransaction(hash) + if response == "" { + return "", fmt.Errorf("Transaction does not exist ") + } + schemaID := "" + flag := false + //LedgerEntryType, err := jsonparser.GetString([]byte(response), "result", "meta", "AffectedNodes", "[0]", "CreatedNode", "LedgerEntryType") + jsonparser.ArrayEach([]byte(response), func(value []byte, dataType jsonparser.ValueType, offset int, err error) { + LedgerEntryType, err := jsonparser.GetString(value, "CreatedNode", "LedgerEntryType") + if err == nil { + if LedgerEntryType == "Schema" { + schemaID, _ = jsonparser.GetString([]byte(value), "CreatedNode", "LedgerIndex") + flag = true + } + } + + }, "result", "meta", "AffectedNodes") + if flag { + return schemaID, nil + } + return "", fmt.Errorf("Invalid parameter") +} +func (c *Chainsql) GetTransaction(hash string) (string, error) { + return c.client.GetTransaction(hash) +} + +func (c *Chainsql) GetTransactionResult(hash string) (string, error) { + return c.client.GetTransactionResult(hash) +} + +// PrepareTx prepare tx json for submit +func (c *Chainsql) PrepareTx() (Signer, error) { + var tx Signer + var err error + switch c.op.TxType { + case SCHEMA_CREATE: + tx, err = c.createSchema() + break + case SCHEMA_MODIFY: + tx, err = c.modifySchema() + break + case SCHEMA_DELETE: + tx, err = c.deleteSchema() + break + default: + } + if err != nil { + return nil, err + } + + return c.prepareTxBase(tx) +} + +func (c *Chainsql) prepareTxBase(tx Signer) (Signer, error) { + + //tx := c.op.Signer + seq, err := net.PrepareRipple(c.client) + if err != nil { + return nil, err + } + + var fee int64 = 10 + var last uint32 + if c.client.ServerInfo.Updated { + last = uint32(c.client.ServerInfo.LedgerIndex + util.Seqinterval) + fee = int64(c.client.ServerInfo.ComputeFee()) + } else { + ledgerIndex, err := c.client.GetLedgerVersion() + if err != nil { + return nil, err + } + last = uint32(ledgerIndex + util.Seqinterval) + fee = 50 + } + + if tx.GetRaw() != "" { + fee += util.GetExtraFee(tx.GetRaw(), c.client.ServerInfo.DropsPerByte) + } else if tx.GetStatements() != "" { + fee += util.GetExtraFee(tx.GetStatements(), c.client.ServerInfo.DropsPerByte) + } + + finalFee, err := NewNativeValue(fee) + if err != nil { + return nil, err + } + account, err := NewAccountFromAddress(c.client.Auth.Address) + if err != nil { + return nil, err + } + tx.SetTxBase(seq, *finalFee, &last, *account) + return tx, nil } diff --git a/core/ripple.go b/core/ripple.go index f34e1ae..2c40c7d 100644 --- a/core/ripple.go +++ b/core/ripple.go @@ -2,7 +2,10 @@ package core import ( "fmt" + "github.com/buger/jsonparser" + "strconv" + . "github.com/ChainSQL/go-chainsql-api/data" "github.com/ChainSQL/go-chainsql-api/net" ) @@ -10,6 +13,27 @@ import ( type Base struct { } +//OpInfo is the opearting details +// type TransactionRequest struct { +// TransactionType string +// Amount Amount +// Destination string +// Query []interface{} +// } + +//TxInfo is the opearting details +type TxInfo struct { + Raw string + TxType TransactionType + Query []interface{} +} + +// type Amount struct { +// Value string `json:"value"` +// Currency string `json:"currency"` +// Account string `json:"account"` +// } + func (b *Base) Say() { fmt.Println("base") } @@ -22,6 +46,7 @@ func (b *Base) Say2() { type Ripple struct { *Base client *net.Client + op *TxInfo SubmitBase } @@ -29,17 +54,116 @@ func (r *Ripple) Say() { fmt.Println("Ripple") } -func NewRipple() *Ripple { +func NewRipple(client *net.Client) *Ripple { ripple := &Ripple{ Base: &Base{}, - client: net.NewClient(), + client: client, + op: &TxInfo{ + Query: make([]interface{}, 0), + }, } ripple.SubmitBase.client = ripple.client ripple.SubmitBase.IPrepare = ripple return ripple } -func (r *Ripple) Pay(accountId string, value string) *Ripple { +func (r *Ripple) Pay(accountId string, value int64) *Ripple { + r.op.TxType = PAYMENT + r.op.Raw = "{\"AccountId\": \"" + accountId + "\", \"Value\": \"" + strconv.FormatInt(value,10) + "\"}" return r } + +func (r *Ripple) pay(raw string) (Signer, error) { + accountId, _ := jsonparser.GetString([]byte(raw), "AccountId") + strValue, _ := jsonparser.GetString([]byte(raw), "Value") + value, _ := strconv.ParseInt(strValue, 10, 64) + + valueTemp, _ := NewNativeValue(value) + currency_zxc, _ := NewCurrency("ZXC") + amount := Amount{ + Value: valueTemp, + Currency: currency_zxc, + } + return r.PayToNode(accountId, amount) +} + +func (r *Ripple) PayToNode(accountId string, amount Amount) (Signer, error) { + + // if !amount.Currency.IsNative() { + // accountData, err := r.client.GetAccountInfo(string(amount.Issuer)) + // if err != nil { + // log.Println("get issuer %s", err) + // } + + // if accountData != "" { + // //var feeMin, feeMax = "", "" + // //var lFeeRate = Value(0) + // var mapObj map[string]interface{} + // va := amount.Value + // json.Unmarshal([]byte(accountData), &mapObj) + // feeMin := mapObj["TransferFeeMin"].(Value) + // feeMax := mapObj["TransferFeeMax"].(Value) + // lFeeRate := mapObj["TransferRate"].(Value) + // fee := Value() + // if feeMin.IsZero() || feeMax.IsZero() || lFeeRate.IsZero() { + // if feeMin == feeMax { + // fee = feeMin.Float() + // } else if !lFeeRate.IsZero() { + // // fee = FloatOperation.accMul(parseFloat(value), data.rate - 1); + // fee = va.Multiply(lFeeRate) + // if !feeMin.IsZero() { + // if + // fee = + // } + // if feeMax.IsZero() { + // fee = Math.min(fee, parseFloat(data.max)) + // } + // // + // value = value.add(fee) + // } + // } + // } + // } + destination, err := NewAccountFromAddress(accountId) + if err != nil { + return nil,err + } + payment := &Payment{ + //SendMax: nil, + Destination: *destination, + Amount: amount, + } + payment.TransactionType = PAYMENT + account, err := NewAccountFromAddress(r.client.Auth.Address) + if err != nil { + return nil, err + } + payment.Account = *account + seq, err := net.PrepareRipple(r.client) + if err != nil { + return nil, err + } + payment.Sequence = seq + valueTemp, _ := NewNativeValue(10) + payment.Fee = *valueTemp + var sign Signer = payment + return sign, nil +} + +//PrepareTx prepare tx json for submit +func (r *Ripple) PrepareTx() (Signer, error) { + var tx Signer + var err error + switch r.op.TxType { + case PAYMENT: + tx, err = r.pay(r.op.Raw) + break + default: + } + if err != nil { + return nil, err + } + return tx, nil + +} diff --git a/core/submit.go b/core/submit.go index 4fad1ba..9b2a576 100644 --- a/core/submit.go +++ b/core/submit.go @@ -83,8 +83,15 @@ func (s *SubmitBase) doSubmit() *TxResult { ErrorMessage: err.Error(), } } + /*var hasher hash.Hash + if key.Type() == common.SoftGMAlg { + hasher = sm3.New() + }else { + hasher = sha512.New() + } +*/ sequenceZero := uint32(0) - err = Sign(tx, key, &sequenceZero) + err = Sign(tx, key, &sequenceZero,key.Type()) if err != nil { log.Printf("doSubmit error:%s\n", err) return &TxResult{ @@ -93,7 +100,7 @@ func (s *SubmitBase) doSubmit() *TxResult { } } - _, blob, err := Raw(tx) + _, blob, err := Raw(tx, key.Type()) if err != nil { log.Printf("doSubmit error:%s\n", err) return &TxResult{ diff --git a/crypto/account.go b/crypto/account.go index e7e5a9a..e76cdbb 100644 --- a/crypto/account.go +++ b/crypto/account.go @@ -4,17 +4,27 @@ import ( "crypto/rand" "encoding/json" "fmt" + "github.com/ChainSQL/go-chainsql-api/common" "log" + "strings" ) //Account define the account format type Account struct { - Address string `json:"address"` - PublicKey string `json:"publicKey"` - PublicKeyHex string `json:"publicKeyHex"` - PrivateKey string `json:"privateKey"` + Address string `json:"address"` + PublicKeyBase58 string `json:"publicKeyBase58"` + PublicKeyHex string `json:"publicKeyHex"` + PrivateSeed string `json:"privateSeed"` + PrivateKey interface{} `json:"privateKey"` + PublicKey interface{} `json:"publicKey"` } +type SeedKey struct { + Seed string `json:"seed"` + PublicKey string `json:"publicKey"` +} + +//生成特殊地址仍然使用此方法 func GenerateAccount(args ...string) (string, error) { var seed Hash var err error @@ -43,11 +53,22 @@ func GenerateAccount(args ...string) (string, error) { sequenceZero := uint32(0) account, _ := AccountId(key, &sequenceZero) publicKey, _ := AccountPublicKey(key, &sequenceZero) + pk, err := key.PK(&sequenceZero) + if err != nil { + return "", err + } + + pub, err := key.PUB(&sequenceZero) + if err != nil { + return "", err + } generated := Account{ - Address: account.String(), - PublicKey: publicKey.String(), - PublicKeyHex: fmt.Sprintf("%X", key.Public(&sequenceZero)), - PrivateKey: seed.String(), + Address: account.String(), + PublicKeyBase58: publicKey.String(), + PublicKeyHex: fmt.Sprintf("%X", key.Public(&sequenceZero)), + PrivateSeed: seed.String(), + PrivateKey: pk, + PublicKey: pub, } jsonStr, err := json.Marshal(generated) if err != nil { @@ -56,8 +77,72 @@ func GenerateAccount(args ...string) (string, error) { return string(jsonStr), nil } -func ValidationCreate() (string, error) { - generated := Account{} +func GenerateAddress(options string) (string, error) { + var seed *Seed + var err error + var key Key + if strings.Contains(options, "secret") && !strings.Contains(options, "algorithm") { + return "", fmt.Errorf("Invalid parameter") + } + seed, err = GenerateSeed(options) + if err != nil { + return "", err + } + sVersion := seed.version + switch sVersion { + case common.Ed25519: + key, err = NewEd25519Key(seed.SeedHash.Payload()) + break + case common.SoftGMAlg: + key, err = GenerateKeyPair(seed) + break + case common.ECDSA: + key, err = NewECDSAKey(seed.SeedHash.Payload()) + break + default: + key, err = NewECDSAKey(seed.SeedHash.Payload()) + } + if err != nil { + return "", err + } + + sequenceZero := uint32(0) + account, err := AccountId(key, &sequenceZero) + if err != nil { + return "", err + } + publicKey, err := AccountPublicKey(key, &sequenceZero) + if err != nil { + return "", err + } + var privSeed Hash + if sVersion == common.SoftGMAlg { + privSeed, err = AccountPrivateKey(key, &sequenceZero) + if err != nil { + return "", err + } + } else { + privSeed = seed.SeedHash + } + pk, err := key.PK(&sequenceZero) + if err != nil { + return "", err + } + + pub, err := key.PUB(&sequenceZero) + if err != nil { + return "", err + } + + generated := Account{ + Address: account.String(), + PublicKeyBase58: publicKey.String(), + PublicKeyHex: fmt.Sprintf("%X", key.Public(&sequenceZero)), + PrivateSeed: privSeed.String(), + PrivateKey: pk, + PublicKey: pub, + } + jsonStr, err := json.Marshal(generated) if err != nil { return "", err @@ -65,8 +150,98 @@ func ValidationCreate() (string, error) { return string(jsonStr), nil } -func GetAccountInfo(address string) (string, error) { - generated := Account{} +func GenerateAddressObj(options string) (*Account, error) { + var seed *Seed + var err error + var key Key + if strings.Contains(options, "secret") && !strings.Contains(options, "algorithm") { + return nil, fmt.Errorf("Invalid parameter") + } + seed, err = GenerateSeed(options) + if err != nil { + return nil, err + } + sVersion := seed.version + sequenceZero := uint32(0) + switch sVersion { + case common.Ed25519: + key, err = NewEd25519Key(seed.SeedHash.Payload()) + break + case common.SoftGMAlg: + key, err = GenerateKeyPair(seed) + break + case common.ECDSA: + key1 := &ecdsaKey{} + key1, err = NewECDSAKey(seed.SeedHash.Payload()) + key = key1.GenerateEcdsaKey(sequenceZero) + break + default: + key, err = NewECDSAKey(seed.SeedHash.Payload()) + } + + if err != nil { + return nil, err + } + + account, err := AccountId(key, nil) + if err != nil { + return nil, err + } + publicKey, err := AccountPublicKey(key, nil) + if err != nil { + return nil, err + } + var privSeed Hash + if sVersion == common.SoftGMAlg { + privSeed, err = AccountPrivateKey(key, nil) + if err != nil { + return nil, err + } + } else { + privSeed = seed.SeedHash + } + pk, err := key.PK(nil) + if err != nil { + return nil, err + } + + pub, err := key.PUB(nil) + if err != nil { + return nil, err + } + + return &Account{ + Address: account.String(), + PublicKeyBase58: publicKey.String(), + PublicKeyHex: fmt.Sprintf("%X", key.Public(nil)), + PrivateSeed: privSeed.String(), + PrivateKey: pk, + PublicKey: pub, + }, nil +} + +func ValidationCreate() (string, error) { + var seed Hash + var err error + var key *ecdsaKey + rndBytes := make([]byte, 16) + if _, err := rand.Read(rndBytes); err != nil { + return "", err + } + seed, err = GenerateFamilySeed(string(rndBytes)) + if err != nil { + return "", err + } + key, err = NewECDSAKey(seed.Payload()) + if err != nil { + log.Println(err) + return "", err + } + publicKey, _ := NodePublicKey(key) + generated := SeedKey{ + Seed: seed.String(), + PublicKey: publicKey.String(), + } jsonStr, err := json.Marshal(generated) if err != nil { return "", err diff --git a/crypto/base58.go b/crypto/base58.go index 4fbe1da..c96999c 100644 --- a/crypto/base58.go +++ b/crypto/base58.go @@ -1,86 +1,86 @@ -package crypto - -import ( - "bytes" - "fmt" - "math/big" - "strings" -) - -// Purloined from https://github.com/conformal/btcutil/ - -var bigRadix = big.NewInt(58) -var bigZero = big.NewInt(0) - -// Base58Decode decodes a modified base58 string to a byte slice and checks checksum. -func Base58Decode(b, alphabet string) ([]byte, error) { - if len(b) < 5 { - return nil, fmt.Errorf("Base58 string too short: %s", b) - } - answer := big.NewInt(0) - j := big.NewInt(1) - - for i := len(b) - 1; i >= 0; i-- { - tmp := strings.IndexAny(alphabet, string(b[i])) - if tmp == -1 { - return nil, fmt.Errorf("Bad Base58 string: %s", b) - } - idx := big.NewInt(int64(tmp)) - tmp1 := big.NewInt(0) - tmp1.Mul(j, idx) - - answer.Add(answer, tmp1) - j.Mul(j, bigRadix) - } - - tmpval := answer.Bytes() - - var numZeros int - for numZeros = 0; numZeros < len(b); numZeros++ { - if b[numZeros] != alphabet[0] { - break - } - } - flen := numZeros + len(tmpval) - val := make([]byte, flen, flen) - copy(val[numZeros:], tmpval) - - // Check checksum - checksum := DoubleSha256(val[0 : len(val)-4]) - expected := val[len(val)-4:] - if !bytes.Equal(checksum[0:4], expected) { - return nil, fmt.Errorf("Bad Base58 checksum: %v expected %v", checksum, expected) - } - return val, nil -} - -// Base58Encode encodes a byte slice to a modified base58 string. -func Base58Encode(b []byte, alphabet string) string { - checksum := DoubleSha256(b) - b = append(b, checksum[0:4]...) - x := new(big.Int) - x.SetBytes(b) - - answer := make([]byte, 0) - for x.Cmp(bigZero) > 0 { - mod := new(big.Int) - x.DivMod(x, bigRadix, mod) - answer = append(answer, alphabet[mod.Int64()]) - } - - // leading zero bytes - for _, i := range b { - if i != 0 { - break - } - answer = append(answer, alphabet[0]) - } - - // reverse - alen := len(answer) - for i := 0; i < alen/2; i++ { - answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i] - } - - return string(answer) -} +package crypto + +import ( + "bytes" + "fmt" + "math/big" + "strings" +) + +// Purloined from https://github.com/conformal/btcutil/ + +var bigRadix = big.NewInt(58) +var bigZero = big.NewInt(0) + +// Base58Decode decodes a modified base58 string to a byte slice and checks checksum. +func Base58Decode(b, alphabet string) ([]byte, error) { + if len(b) < 5 { + return nil, fmt.Errorf("Base58 string too short: %s", b) + } + answer := big.NewInt(0) + j := big.NewInt(1) + + for i := len(b) - 1; i >= 0; i-- { + tmp := strings.IndexAny(alphabet, string(b[i])) + if tmp == -1 { + return nil, fmt.Errorf("Bad Base58 string: %s", b) + } + idx := big.NewInt(int64(tmp)) + tmp1 := big.NewInt(0) + tmp1.Mul(j, idx) + + answer.Add(answer, tmp1) + j.Mul(j, bigRadix) + } + + tmpval := answer.Bytes() + + var numZeros int + for numZeros = 0; numZeros < len(b); numZeros++ { + if b[numZeros] != alphabet[0] { + break + } + } + flen := numZeros + len(tmpval) + val := make([]byte, flen, flen) + copy(val[numZeros:], tmpval) + + // Check checksum + checksum := DoubleSha256(val[0 : len(val)-4]) + expected := val[len(val)-4:] + if !bytes.Equal(checksum[0:4], expected) { + return nil, fmt.Errorf("Bad Base58 checksum: %v expected %v", checksum, expected) + } + return val, nil +} + +// Base58Encode encodes a byte slice to a modified base58 string. +func Base58Encode(b []byte, alphabet string) string { + checksum := DoubleSha256(b) + b = append(b, checksum[0:4]...) + x := new(big.Int) + x.SetBytes(b) + + answer := make([]byte, 0) + for x.Cmp(bigZero) > 0 { + mod := new(big.Int) + x.DivMod(x, bigRadix, mod) + answer = append(answer, alphabet[mod.Int64()]) + } + + // leading zero bytes + for _, i := range b { + if i != 0 { + break + } + answer = append(answer, alphabet[0]) + } + + // reverse + alen := len(answer) + for i := 0; i < alen/2; i++ { + answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i] + } + + return string(answer) +} diff --git a/crypto/const.go b/crypto/const.go index 12ebcb1..ad5db1d 100644 --- a/crypto/const.go +++ b/crypto/const.go @@ -21,6 +21,13 @@ const ( RIPPLE_ACCOUNT_PUBLIC HashVersion = 35 ) +// const ( +// ED25519 = 0 +// K256 = 1 +// SM = 3 +// SOFT_SM = 4 +// ) + var hashTypes = [...]struct { Description string Prefix byte @@ -31,6 +38,6 @@ var hashTypes = [...]struct { RIPPLE_NODE_PUBLIC: {"Validation public key for node.", 'n', 33, 53}, RIPPLE_NODE_PRIVATE: {"Validation private key for node.", 'p', 32, 52}, RIPPLE_FAMILY_SEED: {"Family seed.", 's', 16, 29}, - RIPPLE_ACCOUNT_PRIVATE: {"Account private key.", 'p', 32, 52}, - RIPPLE_ACCOUNT_PUBLIC: {"Account public key.", 'a', 33, 53}, + RIPPLE_ACCOUNT_PRIVATE: {"Account private key.", 'p', 65, 52}, + RIPPLE_ACCOUNT_PUBLIC: {"Account public key.", 'a', 65, 53}, } diff --git a/crypto/ecdsa.go b/crypto/ecdsa.go index 0ccb0b4..eecf2ce 100644 --- a/crypto/ecdsa.go +++ b/crypto/ecdsa.go @@ -5,6 +5,8 @@ import ( "encoding/binary" "math/big" + "github.com/ChainSQL/go-chainsql-api/common" + "github.com/btcsuite/btcd/btcec" ) @@ -21,9 +23,21 @@ type ecdsaKey struct { func newKey(seed []byte) *btcec.PrivateKey { inc := big.NewInt(0).SetBytes(seed) inc.Lsh(inc, 32) + accLen := len(seed) + 4 for key := big.NewInt(0); ; inc.Add(inc, one) { - key.SetBytes(Sha512Half(inc.Bytes())) + incBytes := inc.Bytes() + + paddLen := accLen - len(incBytes) + finalBytes := make([]byte, accLen) + if paddLen != 0 { + tempBytes := make([]byte, paddLen) + finalBytes = append(tempBytes[:], incBytes[:]...) + } else { + finalBytes = incBytes + } + key.SetBytes(Sha512Half(finalBytes)) if key.Cmp(zero) > 0 && key.Cmp(order) < 0 { + // privKey, _ := btcec.PrivKeyFromBytes(elliptic.S256(), key.Bytes()) privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), key.Bytes()) return privKey } @@ -41,7 +55,7 @@ func NewECDSAKey(seed []byte) (*ecdsaKey, error) { return &ecdsaKey{newKey(seed)}, nil } -func (k *ecdsaKey) generateKey(sequence uint32) *btcec.PrivateKey { +func (k *ecdsaKey) GenerateKey(sequence uint32) *btcec.PrivateKey { seed := make([]byte, btcec.PubKeyBytesLenCompressed+4) copy(seed, k.PubKey().SerializeCompressed()) binary.BigEndian.PutUint32(seed[btcec.PubKeyBytesLenCompressed:], sequence) @@ -51,6 +65,16 @@ func (k *ecdsaKey) generateKey(sequence uint32) *btcec.PrivateKey { return key } +func (k *ecdsaKey) GenerateEcdsaKey(sequence uint32) *ecdsaKey { + seed := make([]byte, btcec.PubKeyBytesLenCompressed+4) + copy(seed, k.PubKey().SerializeCompressed()) + binary.BigEndian.PutUint32(seed[btcec.PubKeyBytesLenCompressed:], sequence) + key := newKey(seed) + key.D.Add(key.D, k.D).Mod(key.D, order) + key.X, key.Y = key.ScalarBaseMult(key.D.Bytes()) + return &ecdsaKey{key} +} + func (k *ecdsaKey) Id(sequence *uint32) []byte { if sequence == nil { return Sha256RipeMD160(k.PubKey().SerializeCompressed()) @@ -62,14 +86,33 @@ func (k *ecdsaKey) Private(sequence *uint32) []byte { if sequence == nil { return k.D.Bytes() } - return k.generateKey(*sequence).D.Bytes() + return k.GenerateKey(*sequence).D.Bytes() +} + +func (k *ecdsaKey) PK(sequence *uint32) (interface{}, error) { + //if sequence == nil { + // return k.PrivateKey, nil + //} + //return k.GenerateKey(*sequence), nil + return k.PrivateKey.ToECDSA(), nil } func (k *ecdsaKey) Public(sequence *uint32) []byte { if sequence == nil { return k.PubKey().SerializeCompressed() } - return k.generateKey(*sequence).PubKey().SerializeCompressed() + + return k.GenerateKey(*sequence).PubKey().SerializeCompressed() } +func (k *ecdsaKey) PUB(sequence *uint32) (interface{}, error) { + //if sequence == nil { + // return k.PublicKey, nil + //} + //return k.GenerateKey(*sequence).PublicKey, nil + return k.PublicKey, nil +} +func (k *ecdsaKey) Type() common.KeyType { + return common.ECDSA +} diff --git a/crypto/ed25519.go b/crypto/ed25519.go index 7e31549..bc0aada 100644 --- a/crypto/ed25519.go +++ b/crypto/ed25519.go @@ -4,15 +4,18 @@ import ( "bytes" "crypto/ed25519" "crypto/rand" + "fmt" + "github.com/ChainSQL/go-chainsql-api/common" ) type ed25519key struct { priv ed25519.PrivateKey + pub ed25519.PublicKey } func checkSequenceIsNil(seq *uint32) { if seq != nil { - panic("Ed25519 keys do not support account families") + fmt.Errorf("Ed25519 keys do not support account families") } } @@ -26,19 +29,36 @@ func (e *ed25519key) Public(seq *uint32) []byte { return append([]byte{0xED}, e.priv[32:]...) } +func (e *ed25519key) PUB(seq *uint32) (interface{}, error) { + //checkSequenceIsNil(seq) + //return append([]byte{0xED}, e.priv[32:]...), nil + return e.pub, nil +} + func (e *ed25519key) Private(seq *uint32) []byte { checkSequenceIsNil(seq) return e.priv[:] } +func (e *ed25519key) PK(seq *uint32) (interface{}, error) { + //checkSequenceIsNil(seq) + //return e.priv[:], nil + return e.priv, nil +} + +func (k *ed25519key) Type() common.KeyType { + return common.Ed25519 +} + func NewEd25519Key(seed []byte) (*ed25519key, error) { r := rand.Reader if seed != nil { r = bytes.NewReader(Sha512Half(seed)) } - _, priv, err := ed25519.GenerateKey(r) + pub, priv, err := ed25519.GenerateKey(r) if err != nil { return nil, err } - return &ed25519key{priv: priv}, nil + key := &ed25519key{priv: priv, pub: pub} + return key, nil } diff --git a/crypto/hash.go b/crypto/hash.go index 392e317..b807585 100644 --- a/crypto/hash.go +++ b/crypto/hash.go @@ -36,6 +36,17 @@ func NewRippleHashCheck(s string, version HashVersion) (Hash, error) { return hash, nil } +// Checks hash matches expected version +func NewRippleSeed(s string, version HashVersion) (*Seed, error) { + keySeed := &Seed{} + hash, err := NewRippleHashCheck(s, version) + if err != nil { + return nil, err + } + keySeed.SeedHash = hash + return keySeed, nil +} + func NewAccountId(b []byte) (Hash, error) { return newHash(b, RIPPLE_ACCOUNT_ID) } diff --git a/crypto/interface.go b/crypto/interface.go index b446935..396d49e 100644 --- a/crypto/interface.go +++ b/crypto/interface.go @@ -1,11 +1,18 @@ package crypto -import "math/big" +import ( + "github.com/ChainSQL/go-chainsql-api/common" + "math/big" +) type Key interface { Private(*uint32) []byte Id(*uint32) []byte Public(*uint32) []byte + Type() common.KeyType + PK(*uint32) (interface{}, error) + PUB(*uint32) (interface{}, error) + //Hasher() Hash } type Hash interface { diff --git a/crypto/key_test.go b/crypto/key_test.go index 84acafa..0f847c0 100644 --- a/crypto/key_test.go +++ b/crypto/key_test.go @@ -18,8 +18,9 @@ func checkHash(h Hash, err error) string { return h.String() } -func checkSignature(c *C, privateKey, publicKey, hash, msg []byte) bool { - sig, err := Sign(privateKey, hash, msg) +func checkSignature(c *C, key Key, publicKey, hash, msg []byte) bool { + sequenceZero := uint32(0) + sig, err := Sign(key, hash, &sequenceZero, msg) c.Assert(err, IsNil) ok, err := Verify(publicKey, hash, msg, sig) c.Assert(err, IsNil) @@ -76,11 +77,11 @@ func (s *KeySuite) TestRippledVectors(c *C) { msg := []byte("Hello, nurse!") hash := Sha512Half(msg) - c.Check(checkSignature(c, key.Private(nil), key.Public(nil), hash, msg), Equals, true) - c.Check(checkSignature(c, key.Private(&sequenceZero), key.Public(&sequenceZero), hash, msg), Equals, true) - c.Check(checkSignature(c, key.Private(&sequenceOne), key.Public(&sequenceOne), hash, msg), Equals, true) - c.Check(checkSignature(c, key.Private(&sequenceOne), key.Public(&sequenceZero), hash, msg), Equals, false) - c.Check(checkSignature(c, key.Private(&sequenceZero), key.Public(&sequenceOne), hash, msg), Equals, false) + c.Check(checkSignature(c, key, key.Public(nil), hash, msg), Equals, true) + c.Check(checkSignature(c, key, key.Public(&sequenceZero), hash, msg), Equals, true) + c.Check(checkSignature(c, key, key.Public(&sequenceOne), hash, msg), Equals, true) + c.Check(checkSignature(c, key, key.Public(&sequenceZero), hash, msg), Equals, false) + c.Check(checkSignature(c, key, key.Public(&sequenceOne), hash, msg), Equals, false) } @@ -102,8 +103,8 @@ func (s *KeySuite) TestEd25119(c *C) { msg := []byte("Hello, nurse!") hash := Sha512Half(msg) - c.Check(checkSignature(c, key.Private(nil), key.Public(nil), hash, msg), Equals, true) - c.Check(checkSignature(c, other.Private(nil), other.Public(nil), hash, msg), Equals, true) - c.Check(checkSignature(c, key.Private(nil), other.Public(nil), hash, msg), Equals, false) - c.Check(checkSignature(c, other.Private(nil), key.Public(nil), hash, msg), Equals, false) + c.Check(checkSignature(c, key, key.Public(nil), hash, msg), Equals, true) + c.Check(checkSignature(c, other, other.Public(nil), hash, msg), Equals, true) + c.Check(checkSignature(c, key, other.Public(nil), hash, msg), Equals, false) + c.Check(checkSignature(c, other, key.Public(nil), hash, msg), Equals, false) } diff --git a/crypto/seed.go b/crypto/seed.go new file mode 100644 index 0000000..91f3812 --- /dev/null +++ b/crypto/seed.go @@ -0,0 +1,74 @@ +package crypto + +import ( + "crypto/rand" + "github.com/ChainSQL/go-chainsql-api/common" + "strings" + + "github.com/buger/jsonparser" +) + +type Seed struct { + SeedHash Hash + version common.KeyType +} + +func GenerateSeed(options string) (*Seed, error) { + var err error + sVersion, _ := jsonparser.GetString([]byte(options), "algorithm") + var version common.KeyType + seed := &Seed{} + switch sVersion { + case "ed25519": + version = common.Ed25519 + break + case "secp256k1": + version = common.ECDSA + break + case "softGMAlg": + version = common.SoftGMAlg + break + default: + version = common.ECDSA + } + seed.version = version + if version == common.SoftGMAlg { + if strings.Contains(options, "secret") { + secret, _ := (jsonparser.GetString([]byte(options), "secret")) + seed.SeedHash, err = newHashFromString(secret) + } else { + seed.SeedHash = nil + } + } else { + if strings.Contains(options, "secret") { + secret, _ := (jsonparser.GetString([]byte(options), "secret")) + seed.SeedHash, err = newHashFromString(secret) + } else { + rndBytes := make([]byte, 16) + if _, err := rand.Read(rndBytes); err != nil { + return nil, err + } + seed.SeedHash, err = GenerateFamilySeed(string(rndBytes)) + } + } + return seed, err +} + +func (s *Seed) GenerateKey(keyType common.KeyType) (Key, error) { + var ( + key Key + err error + ) + switch keyType { + case common.Ed25519: + key, err = NewEd25519Key(s.SeedHash.Payload()) + case common.ECDSA: + key, err = NewECDSAKey(s.SeedHash.Payload()) + case common.SoftGMAlg: + key, err = GenerateKeyPairBySeed(s.SeedHash.Payload()) + } + if err != nil { + return nil, err + } + return key, nil +} diff --git a/crypto/signature.go b/crypto/signature.go index 61ff587..55dd7a8 100644 --- a/crypto/signature.go +++ b/crypto/signature.go @@ -2,17 +2,21 @@ package crypto import ( "crypto/ed25519" + "encoding/hex" "fmt" + "github.com/ChainSQL/go-chainsql-api/common" "github.com/btcsuite/btcd/btcec" ) -func Sign(privateKey, hash, msg []byte) ([]byte, error) { - switch len(privateKey) { - case ed25519.PrivateKeySize: - return signEd25519(privateKey, msg) - case btcec.PrivKeyBytesLen: - return signECDSA(privateKey, hash) +func Sign(key Key, hash []byte, sequence *uint32, msg []byte) ([]byte, error) { + switch key.Type() { + case common.Ed25519: + return signEd25519(key.Private(sequence), msg) + case common.ECDSA: + return signECDSA(key.Private(sequence), hash) + case common.SoftGMAlg: + return signSoftSM(key.Private(sequence), msg) default: return nil, fmt.Errorf("Unknown private key format") } @@ -48,6 +52,7 @@ func verifyEd25519(pubKey, signature, msg []byte) (bool, error) { // Returns DER encoded signature from input hash func signECDSA(privateKey, hash []byte) ([]byte, error) { + // priv, _ := btcec.PrivKeyFromBytes(elliptic.S256(), privateKey) priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), privateKey) sig, err := priv.Sign(hash) if err != nil { @@ -68,3 +73,16 @@ func verifyECDSA(pubKey, signature, hash []byte) (bool, error) { } return sig.Verify(hash, pk), nil } + +func signSoftSM(privateKey, msg []byte) ([]byte, error) { + keyPair, err := PrivKeyFromBytes(privateKey) + if err != nil { + return nil, err + } + sign, err := SmSign(keyPair, msg) + if err != nil { + return nil, err + } + signByte, err := hex.DecodeString(sign) // 转码 + return signByte, nil +} diff --git a/crypto/smalg.go b/crypto/smalg.go new file mode 100644 index 0000000..36cca6a --- /dev/null +++ b/crypto/smalg.go @@ -0,0 +1,164 @@ +package crypto + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "strings" + + "github.com/ChainSQL/go-chainsql-api/common" + + "github.com/ChainSQL/gm-crypto/sm2" + "github.com/ChainSQL/gm-crypto/sm3" +) + +type smKey struct { + PrivateKey string + PublicKey string +} + +func generateKeyPair() (*smKey, error) { + priv, err := sm2.GenerateKey(rand.Reader) + if err != nil { + return nil, err + } + priKey := leftPad(priv.D.Text(16), 64) + Px := leftPad(priv.PublicKey.X.Text(16), 64) + Py := leftPad(priv.PublicKey.Y.Text(16), 64) + pubKey := "47" + Px + Py + private := &smKey{} + private.PrivateKey = strings.ToUpper(priKey) + private.PublicKey = strings.ToUpper(pubKey) + return private, nil +} + +func GenerateKeyPairBySeed(seed []byte) (*smKey, error) { + var err error + seedStr := hex.EncodeToString(seed) + priv, err := sm2.GenerateKeyBySeed(rand.Reader, seedStr) + if err != nil { + return nil, err + } + priKey := leftPad(priv.D.Text(16), 64) + Px := leftPad(priv.PublicKey.X.Text(16), 64) + Py := leftPad(priv.PublicKey.Y.Text(16), 64) + pubKey := "47" + Px + Py + private := &smKey{} + private.PrivateKey = strings.ToUpper(priKey) + private.PublicKey = strings.ToUpper(pubKey) + return private, nil +} + +func PrivKeyFromBytes(privKey []byte) (*sm2.PrivateKey, error) { + seedStr := hex.EncodeToString(privKey) + return sm2.GenerateKeyBySeed(rand.Reader, seedStr) +} + +/*func sm2KeyPairToChainsqlKeyPair(priv *PrivateKey)(*smKey, error){ + priKey := leftPad(priv.D.Text(16), 64) + Px := leftPad(priv.PublicKey.X.Text(16), 64) + Py := leftPad(priv.PublicKey.Y.Text(16), 64) + pubKey := "47"+ Px + Py + private := &smKey{} + private.PrivateKey = strings.ToUpper(priKey) + private.PublicKey = strings.ToUpper(pubKey) + return private,nil +}*/ + +func GenerateKeyPair(seed *Seed) (*smKey, error) { + if seed.SeedHash == nil { + smKeyPair, err := generateKeyPair() + if err != nil { + return nil, err + } + return smKeyPair, nil + } else { + // 在国密算法内部添加新的方法 + smKeyPair, err := GenerateKeyPairBySeed(seed.SeedHash.Payload()) + if err != nil { + return nil, err + } + return smKeyPair, nil + } +} + +/** + * 补全16进制字符串 + */ +func leftPad(input string, num int) string { + if len([]byte(input)) >= num { + return input + } + length := num - len([]byte(input)) + for i := 0; i < length; i++ { + input = "0" + input + } + return input +} + +// GM算法没有seed生成公私钥,因此不存在sequence +func (k *smKey) Id(sequence *uint32) []byte { + return Sha256RipeMD160(k.Public(sequence)) +} + +func (k *smKey) Private(sequence *uint32) []byte { + privateByte, err := hex.DecodeString(k.PrivateKey) // 转码 + if err != nil { + fmt.Printf("PrivateKey transcoding exception ") + } + return privateByte +} + +func (k *smKey) PK(sequence *uint32) (interface{}, error) { + privateByte, err := hex.DecodeString(k.PrivateKey) // 转码 + if err != nil { + fmt.Printf("PrivateKey transcoding exception ") + return nil, fmt.Errorf("PrivateKey transcoding exception ") + } + pk, err := PrivKeyFromBytes(privateByte) + if err != nil { + fmt.Printf("sm2 PrivKeyFromBytes err : %v\n", err) + return nil, err + } + return pk, nil +} + +func (k *smKey) Public(sequence *uint32) []byte { + pubkeyByte, err := hex.DecodeString(k.PublicKey) + if err != nil { + fmt.Printf("PublicKey transcoding exception ") + } + return []byte(pubkeyByte) +} + +func (k *smKey) PUB(sequence *uint32) (interface{}, error) { + privateByte, err := hex.DecodeString(k.PrivateKey) // 转码 + if err != nil { + fmt.Printf("PrivateKey transcoding exception ") + return nil, fmt.Errorf("PrivateKey transcoding exception ") + } + pk, err := PrivKeyFromBytes(privateByte) + if err != nil { + fmt.Printf("sm2 PrivKeyFromBytes err : %v\n", err) + return nil, err + } + return pk.PublicKey, nil +} + +func (k *smKey) Type() common.KeyType { + return common.SoftGMAlg +} + +func SmSign(k *sm2.PrivateKey, msg []byte) (string, error) { + hashed := sm3.SumSM3(msg) + + r, s, err := sm2.SignWithDigest(rand.Reader, k, hashed) + if err != nil { + return "", err + } + /*if !sm2.VerifyWithDigest(&k.PublicKey, hashed, r, s) { + log.Println("err") + }*/ + sigValueHex := leftPad(r.Text(16), 64) + leftPad(s.Text(16), 64) + return strings.ToUpper(sigValueHex), nil +} diff --git a/crypto/util.go b/crypto/util.go index 6914f46..2b8f39a 100644 --- a/crypto/util.go +++ b/crypto/util.go @@ -1,55 +1,55 @@ -package crypto - -import ( - "crypto/sha256" - "crypto/sha512" - "encoding/hex" - "fmt" - - "golang.org/x/crypto/ripemd160" -) - -// Write operations in a hash.Hash never return an error - -// Returns first 32 bytes of a SHA512 of the input bytes -func Sha512Half(b []byte) []byte { - hasher := sha512.New() - hasher.Write(b) - return hasher.Sum(nil)[:32] -} - -// Returns first 16 bytes of a SHA512 of the input bytes -func Sha512Quarter(b []byte) []byte { - hasher := sha512.New() - hasher.Write(b) - return hasher.Sum(nil)[:16] -} - -func DoubleSha256(b []byte) []byte { - hasher := sha256.New() - hasher.Write(b) - sha := hasher.Sum(nil) - hasher.Reset() - hasher.Write(sha) - return hasher.Sum(nil) -} - -func Sha256RipeMD160(b []byte) []byte { - ripe := ripemd160.New() - sha := sha256.New() - sha.Write(b) - ripe.Write(sha.Sum(nil)) - return ripe.Sum(nil) -} - -func H2B(s string) ([]byte, error) { - return hex.DecodeString(s) -} - -func B2H(b []byte) string { - return fmt.Sprintf("%X", b) -} - -func B2H32(b [32]byte) string { - return fmt.Sprintf("%X", b) -} +package crypto + +import ( + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "fmt" + + "golang.org/x/crypto/ripemd160" +) + +// Write operations in a hash.Hash never return an error + +// Returns first 32 bytes of a SHA512 of the input bytes +func Sha512Half(b []byte) []byte { + hasher := sha512.New() + hasher.Write(b) + return hasher.Sum(nil)[:32] +} + +// Returns first 16 bytes of a SHA512 of the input bytes +func Sha512Quarter(b []byte) []byte { + hasher := sha512.New() + hasher.Write(b) + return hasher.Sum(nil)[:16] +} + +func DoubleSha256(b []byte) []byte { + hasher := sha256.New() + hasher.Write(b) + sha := hasher.Sum(nil) + hasher.Reset() + hasher.Write(sha) + return hasher.Sum(nil) +} + +func Sha256RipeMD160(b []byte) []byte { + ripe := ripemd160.New() + sha := sha256.New() + sha.Write(b) + ripe.Write(sha.Sum(nil)) + return ripe.Sum(nil) +} + +func H2B(s string) ([]byte, error) { + return hex.DecodeString(s) +} + +func B2H(b []byte) string { + return fmt.Sprintf("%X", b) +} + +func B2H32(b [32]byte) string { + return fmt.Sprintf("%X", b) +} diff --git a/data/amount.go b/data/amount.go index cea36bd..df6279d 100644 --- a/data/amount.go +++ b/data/amount.go @@ -252,7 +252,7 @@ func NewExchangeRate(a, b *Amount) (ExchangeRate, error) { return 0, nil } if rate.offset >= -100 || rate.offset <= 155 { - panic("Impossible Rate") + return 0, fmt.Errorf("Impossible Rate") } return ExchangeRate(uint64(rate.offset+100)<<54 | uint64(rate.num)), nil } diff --git a/data/decoder.go b/data/decoder.go index e31ae47..8a08d27 100644 --- a/data/decoder.go +++ b/data/decoder.go @@ -3,6 +3,7 @@ package data import ( "errors" "fmt" + "github.com/ChainSQL/go-chainsql-api/common" "reflect" ) @@ -81,7 +82,7 @@ func ReadTransaction(r Reader) (Transaction, error) { // ReadTransactionAndMetadata combines the inputs from the two // readers into a TransactionWithMetaData -func ReadTransactionAndMetadata(tx, meta Reader, hash Hash256, ledger uint32) (*TransactionWithMetaData, error) { +func ReadTransactionAndMetadata(tx, meta Reader, hash Hash256, ledger uint32, keyType common.KeyType) (*TransactionWithMetaData, error) { t, err := ReadTransaction(tx) if err != nil { return nil, err @@ -95,7 +96,7 @@ func ReadTransactionAndMetadata(tx, meta Reader, hash Hash256, ledger uint32) (* return nil, err } *txm.GetHash() = hash - if txm.Id, err = NodeId(txm); err != nil { + if txm.Id, err = NodeId(txm, keyType); err != nil { return nil, err } return txm, nil diff --git a/data/encoder.go b/data/encoder.go index a020581..2348134 100644 --- a/data/encoder.go +++ b/data/encoder.go @@ -4,47 +4,56 @@ import ( "bytes" "crypto/sha512" "fmt" + "hash" "io" "reflect" "sort" "strings" + + "github.com/ChainSQL/gm-crypto/sm3" + "github.com/ChainSQL/go-chainsql-api/common" ) -func Raw(h Hashable) (Hash256, []byte, error) { - return raw(h, h.Prefix(), false) +func Raw(h Hashable, keyType common.KeyType) (Hash256, []byte, error) { + return raw(h, h.Prefix(), false, keyType) } -func NodeId(h Hashable) (Hash256, error) { - nodeid, _, err := raw(h, h.Prefix(), false) +func NodeId(h Hashable, keyType common.KeyType) (Hash256, error) { + nodeid, _, err := raw(h, h.Prefix(), false, keyType) return nodeid, err } -func SigningHash(s Signer) (Hash256, []byte, error) { - return raw(s, s.SigningPrefix(), true) +func SigningHash(s Signer, keyType common.KeyType) (Hash256, []byte, error) { + return raw(s, s.SigningPrefix(), true, keyType) } -func Node(h Storer) (Hash256, []byte, error) { +func Node(h Storer, keyType common.KeyType) (Hash256, []byte, error) { var header bytes.Buffer for _, v := range []interface{}{h.Ledger(), h.Ledger(), h.NodeType(), h.Prefix()} { if err := write(&header, v); err != nil { return zero256, nil, err } } - key, value, err := raw(h, h.Prefix(), true) + key, value, err := raw(h, h.Prefix(), true, keyType) if err != nil { return zero256, nil, err } return key, append(header.Bytes(), value...), nil } -func raw(value interface{}, prefix HashPrefix, ignoreSigningFields bool) (Hash256, []byte, error) { +func raw(value interface{}, prefix HashPrefix, ignoreSigningFields bool, keyType common.KeyType) (Hash256, []byte, error) { buf := new(bytes.Buffer) - hasher := sha512.New() + var hasher hash.Hash + if keyType == common.SoftGMAlg { + hasher = sm3.New() + } else { + hasher = sha512.New() + } multi := io.MultiWriter(buf, hasher) if err := write(hasher, prefix); err != nil { return zero256, nil, err } - if err := writeRaw(multi, value, ignoreSigningFields); err != nil { + if err := writeRaw(multi, value, ignoreSigningFields, keyType); err != nil { return zero256, nil, err } var hash Hash256 @@ -53,7 +62,7 @@ func raw(value interface{}, prefix HashPrefix, ignoreSigningFields bool) (Hash25 } // Disgusting node format and ordering handled here -func writeRaw(w io.Writer, value interface{}, ignoreSigningFields bool) error { +func writeRaw(w io.Writer, value interface{}, ignoreSigningFields bool, keyType common.KeyType) error { switch v := value.(type) { case *Ledger: return write(w, v.LedgerHeader) @@ -68,7 +77,7 @@ func writeRaw(w io.Writer, value interface{}, ignoreSigningFields bool) error { return write(w, v) } case *TransactionWithMetaData: - txid, tx, err := Raw(v.Transaction) + txid, tx, err := Raw(v.Transaction, keyType) if err != nil { return err } diff --git a/data/factory.go b/data/factory.go index cce0a10..a8b0ef8 100644 --- a/data/factory.go +++ b/data/factory.go @@ -43,6 +43,11 @@ const ( TRUST_SET TransactionType = 20 TABLE_LIST_SET TransactionType = 21 SQLSTATEMENT TransactionType = 22 + SQLTRANSACTION TransactionType = 23 + CONTRACT TransactionType = 24 + SCHEMA_CREATE TransactionType = 25 + SCHEMA_MODIFY TransactionType = 26 + SCHEMA_DELETE TransactionType = 28 ACCOUNT_DELETE TransactionType = 51 AMENDMENT TransactionType = 100 SET_FEE TransactionType = 101 @@ -88,6 +93,9 @@ var TxFactory = [...]func() Transaction{ CHECK_CREATE: func() Transaction { return &CheckCreate{TxBase: TxBase{TransactionType: CHECK_CREATE}} }, CHECK_CASH: func() Transaction { return &CheckCash{TxBase: TxBase{TransactionType: CHECK_CASH}} }, CHECK_CANCEL: func() Transaction { return &CheckCancel{TxBase: TxBase{TransactionType: CHECK_CANCEL}} }, + SCHEMA_CREATE: func() Transaction { return &SchemaCreate{TxBase: TxBase{TransactionType: SCHEMA_CREATE}} }, + SCHEMA_MODIFY: func() Transaction { return &SchemaModify{TxBase: TxBase{TransactionType: SCHEMA_MODIFY}} }, + SCHEMA_DELETE: func() Transaction { return &SchemaDelete{TxBase: TxBase{TransactionType: SCHEMA_DELETE}} }, } var ledgerEntryNames = [...]string{ @@ -144,6 +152,11 @@ var txNames = [...]string{ CHECK_CANCEL: "CheckCancel", TABLE_LIST_SET: "TableListSet", SQLSTATEMENT: "SQLStatement", + SQLTRANSACTION: "SQLTransaction", + CONTRACT: "Contract", + SCHEMA_CREATE: "SchemaCreate", + SCHEMA_MODIFY: "SchemaModify", + SCHEMA_DELETE: "SchemaDelete", } var txTypes = map[string]TransactionType{ @@ -168,6 +181,11 @@ var txTypes = map[string]TransactionType{ "CheckCancel": CHECK_CANCEL, "TableListSet": TABLE_LIST_SET, "SQLStatement": SQLSTATEMENT, + "SQLTransaction": SQLTRANSACTION, + "Contract": CONTRACT, + "SchemaCreate": SCHEMA_CREATE, + "SchemaModify": SCHEMA_MODIFY, + "SchemaDelete": SCHEMA_DELETE, } var HashableTypes []string diff --git a/data/format.go b/data/format.go index ace0a26..d754341 100644 --- a/data/format.go +++ b/data/format.go @@ -166,6 +166,8 @@ var encodings = map[enc]string{ enc{ST_HASH256, 21}: "Digest", enc{ST_HASH256, 22}: "Channel", enc{ST_HASH256, 24}: "CheckID", + enc{ST_HASH256, 58}: "AnchorLedgerHash", + enc{ST_HASH256, 59}: "SchemaID", // currency amount (common) enc{ST_AMOUNT, 1}: "Amount", enc{ST_AMOUNT, 2}: "Balance", @@ -203,16 +205,18 @@ var encodings = map[enc]string{ enc{ST_VL, 51}: "TableName", enc{ST_VL, 52}: "Raw", enc{ST_VL, 54}: "AutoFillField", + enc{ST_VL, 68}: "SchemaName", + enc{ST_VL, 69}: "Endpoint", // account - enc{ST_ACCOUNT, 1}: "Account", - enc{ST_ACCOUNT, 2}: "Owner", - enc{ST_ACCOUNT, 3}: "Destination", - enc{ST_ACCOUNT, 4}: "Issuer", - enc{ST_ACCOUNT, 5}: "Authorize", - enc{ST_ACCOUNT, 6}: "Unauthorize", - enc{ST_ACCOUNT, 7}: "Target", - enc{ST_ACCOUNT, 8}: "RegularKey", - + enc{ST_ACCOUNT, 1}: "Account", + enc{ST_ACCOUNT, 2}: "Owner", + enc{ST_ACCOUNT, 3}: "Destination", + enc{ST_ACCOUNT, 4}: "Issuer", + enc{ST_ACCOUNT, 5}: "Authorize", + enc{ST_ACCOUNT, 6}: "Unauthorize", + enc{ST_ACCOUNT, 7}: "Target", + enc{ST_ACCOUNT, 8}: "RegularKey", + enc{ST_ACCOUNT, 53}: "SchemaAdmin", // inner object enc{ST_OBJECT, 1}: "EndOfObject", enc{ST_OBJECT, 2}: "TransactionMetaData", @@ -229,6 +233,9 @@ var encodings = map[enc]string{ enc{ST_OBJECT, 16}: "Signer", enc{ST_OBJECT, 18}: "Majority", enc{ST_OBJECT, 50}: "Table", + enc{ST_OBJECT, 52}: "Validator", + enc{ST_OBJECT, 53}: "Peer", + // array of objects enc{ST_ARRAY, 1}: "EndOfArray", enc{ST_ARRAY, 2}: "SigningAccounts", @@ -242,12 +249,15 @@ var encodings = map[enc]string{ enc{ST_ARRAY, 51}: "Tables", // array of objects (uncommon) enc{ST_ARRAY, 16}: "Majorities", + enc{ST_ARRAY, 53}: "Validators", + enc{ST_ARRAY, 54}: "PeerList", // 8-bit unsigned integers (common) enc{ST_UINT8, 1}: "CloseResolution", enc{ST_UINT8, 2}: "Method", enc{ST_UINT8, 3}: "TransactionResult", // 8-bit unsigned integers (uncommon) enc{ST_UINT8, 16}: "TickSize", + enc{ST_UINT8, 28}: "SchemaStrategy", // 160-bit (common) enc{ST_HASH160, 1}: "TakerPaysCurrency", enc{ST_HASH160, 2}: "TakerPaysIssuer", diff --git a/data/hash.go b/data/hash.go index 8f3e7af..d7850c8 100644 --- a/data/hash.go +++ b/data/hash.go @@ -4,43 +4,43 @@ import ( "bytes" "encoding/hex" "fmt" + "regexp" "strings" + "github.com/ChainSQL/go-chainsql-api/common" "github.com/ChainSQL/go-chainsql-api/crypto" ) -type KeyType int - const ( - ECDSA KeyType = 0 - Ed25519 KeyType = 1 + PUBKEY_LENGTH_GM int = 65 + PUBKEYL_ENGTH_COMMON int = 33 ) -func (keyType KeyType) String() string { - switch keyType { - case ECDSA: - return "ECDSA" - case Ed25519: - return "Ed25519" - default: - return "unknown key type" - } -} + type Hash128 [16]byte type Hash160 [20]byte type Hash256 [32]byte type Vector256 []Hash256 type VariableLength []byte -type PublicKey [33]byte + +//type PublicKey [33]byte +type PublicKey struct { + KeyStore [65]byte + KeyValue []byte + KeyType common.KeyType +} + type Account [20]byte type RegularKey [20]byte -type Seed [16]byte + +//type Seed [16]byte var zero256 Hash256 var zeroAccount Account -var zeroPublicKey PublicKey -var zeroSeed Seed + +//var zeroPublicKey PublicKey +//var zeroSeed Seed func (h *Hash128) Bytes() []byte { if h == nil { @@ -159,8 +159,17 @@ func (v *VariableLength) Bytes() []byte { return []byte(nil) } +func (p *PublicKey) SetKey(kType common.KeyType) { + p.KeyType = kType + if common.SoftGMAlg == kType { + p.KeyValue = p.KeyStore[:PUBKEY_LENGTH_GM] + } else { + p.KeyValue = p.KeyStore[:PUBKEYL_ENGTH_COMMON] + } + +} func (p PublicKey) NodePublicKey() string { - hash, err := crypto.NewNodePublicKey(p[:]) + hash, err := crypto.NewNodePublicKey(p.KeyValue[:]) if err != nil { return "Bad node public key" } @@ -173,12 +182,15 @@ func (p PublicKey) String() string { } func (p PublicKey) IsZero() bool { - return p == zeroPublicKey + if p.KeyValue == nil { + return true + } + return false } func (p *PublicKey) Bytes() []byte { if p != nil { - return p[:] + return p.KeyValue[:] } return []byte(nil) } @@ -266,63 +278,79 @@ func (r *RegularKey) Bytes() []byte { } // Expects address in base58 form -func NewSeedFromAddress(s string) (*Seed, error) { - hash, err := crypto.NewRippleHashCheck(s, crypto.RIPPLE_FAMILY_SEED) - if err != nil { - return nil, err - } - var seed Seed - copy(seed[:], hash.Payload()) - return &seed, nil -} - -func (s Seed) Hash() (crypto.Hash, error) { - return crypto.NewFamilySeed(s[:]) -} - -func (s Seed) String() string { - address, err := s.Hash() - if err != nil { - return fmt.Sprintf("Bad Address: %s", b2h(s[:])) - } - return address.String() -} - -func (s *Seed) Bytes() []byte { - if s != nil { - return s[:] - } - return []byte(nil) -} - -func (s *Seed) Key(keyType KeyType) crypto.Key { - var ( - key crypto.Key - err error - ) - switch keyType { - case Ed25519: - key, err = crypto.NewEd25519Key(s[:]) - case ECDSA: - key, err = crypto.NewECDSAKey(s[:]) - } - if err != nil { - panic(fmt.Sprintf("bad seed: %v", err)) - } - return key -} - -func (s *Seed) AccountId(keyType KeyType, sequence *uint32) Account { - var account Account - copy(account[:], s.Key(keyType).Id(sequence)) - return account -} +// func NewSeedFromAddress(s string, version crypto.HashVersion) (*Seed, error) { +// keySeed := &Seed{} +// hash, err := crypto.NewRippleHashCheck(s, version) +// if err != nil { +// return nil, err +// } +// keySeed.seedHash = hash +// return keySeed, nil +// } + +// func (s *Seed) Hash() (crypto.Hash, error) { +// return crypto.NewFamilySeed(s[:]) +// } + +// func (s Seed) String() string { +// address, err := s.Hash() +// if err != nil { +// return fmt.Sprintf("Bad Address: %s", b2h(s[:])) +// } +// return address.String() +// } + +// func (s *Seed) Bytes() []byte { +// if s != nil { +// return s[:] +// } +// return []byte(nil) +// } + +// func (s *Seed) Key(keyType KeyType) crypto.Key { +// var ( +// key crypto.Key +// err error +// ) +// switch keyType { +// case Ed25519: +// key, err = crypto.NewEd25519Key(s[:]) +// case ECDSA: +// key, err = crypto.NewECDSAKey(s[:]) +// case SoftGMAlg: +// key, err = crypto.GenerateKeyPairBySeed(s[:]) +// } +// if err != nil { +// panic(fmt.Sprintf("bad seed: %v", err)) +// } +// return key +// } + +// func (s *Seed) AccountId(keyType KeyType, sequence *uint32) Account { +// var account Account +// copy(account[:], s.Key(keyType).Id(sequence)) +// return account +// } func KeyFromSecret(secret string) (crypto.Key, error) { - seed, err := NewSeedFromAddress(secret) - if err != nil { - return nil, err + var version crypto.HashVersion + var err error + var seed *crypto.Seed + var regSoftGMSeed = "^[a-zA-Z1-9]{51,51}" + r := regexp.MustCompile(regSoftGMSeed) + if r.MatchString(secret) { + version = crypto.RIPPLE_ACCOUNT_PRIVATE + seed, err = crypto.NewRippleSeed(secret, version) + if err != nil { + return nil, err + } + return seed.GenerateKey(common.SoftGMAlg) + } else { + version = crypto.RIPPLE_FAMILY_SEED + seed, err := crypto.NewRippleSeed(secret, version) + if err != nil { + return nil, err + } + return seed.GenerateKey(common.ECDSA) } - - return seed.Key(ECDSA), nil } diff --git a/data/interface.go b/data/interface.go index 7f01d00..f5ce82f 100644 --- a/data/interface.go +++ b/data/interface.go @@ -1,6 +1,7 @@ package data import ( + "github.com/ChainSQL/go-chainsql-api/common" "io" ) @@ -12,15 +13,18 @@ type Hashable interface { type Signer interface { Hashable - InitialiseForSigning() + InitialiseForSigning(kType common.KeyType) SigningPrefix() HashPrefix GetPublicKey() *PublicKey GetSignature() *VariableLength + SetTxBase(seq uint32, fee Value, astLedgerSequence *uint32, account Account) + GetRaw() string + GetStatements() string } type Router interface { Hashable - SuppressionId() Hash256 + SuppressionId(keyType common.KeyType) Hash256 } type Storer interface { diff --git a/data/json.go b/data/json.go index f9da62b..108bb95 100644 --- a/data/json.go +++ b/data/json.go @@ -464,23 +464,23 @@ func (r *RegularKey) UnmarshalText(b []byte) error { return nil } -func (s Seed) MarshalText() ([]byte, error) { - address, err := s.Hash() - if err != nil { - return nil, err - } - return address.MarshalText() -} +// func (s Seed) MarshalText() ([]byte, error) { +// address, err := s.Hash() +// if err != nil { +// return nil, err +// } +// return address.MarshalText() +// } // Expects base58-encoded account id -func (s *Seed) UnmarshalText(b []byte) error { - account, err := NewSeedFromAddress(string(b)) - if err != nil { - return err - } - copy(s[:], account[:]) - return nil -} +// func (s *Seed) UnmarshalText(b []byte, version crypto.HashVersion) error { +// account, err := NewSeedFromAddress(string(b), version) +// if err != nil { +// return err +// } +// copy(s[:], account[:]) +// return nil +// } func (v VariableLength) MarshalText() ([]byte, error) { return b2h(v), nil @@ -497,12 +497,12 @@ func (p PublicKey) MarshalText() ([]byte, error) { if p.IsZero() { return []byte{}, nil } - return b2h(p[:]), nil + return b2h(p.KeyValue[:]), nil } // Expects public key hex func (p *PublicKey) UnmarshalText(b []byte) error { - _, err := hex.Decode(p[:], b) + _, err := hex.Decode(p.KeyValue[:], b) return err } @@ -518,6 +518,4 @@ func (h *Uint64Hex) UnmarshalText(b []byte) error { return err } -func (keyType KeyType) MarshalText() ([]byte, error) { - return []byte(keyType.String()), nil -} + diff --git a/data/metadata.go b/data/metadata.go index 27b4e82..29b91bd 100644 --- a/data/metadata.go +++ b/data/metadata.go @@ -65,13 +65,17 @@ func (t *TransactionWithMetaData) NodeType() NodeType { return NT_TRANSACTION_NO func (t *TransactionWithMetaData) Ledger() uint32 { return t.LedgerSequence } func (t *TransactionWithMetaData) NodeId() *Hash256 { return &t.Id } -func (t *TransactionWithMetaData) Affects(account Account) bool { +func (t *TransactionWithMetaData) Affects(account Account) (bool, error) { for _, effect := range t.MetaData.AffectedNodes { - if _, final, _, _ := effect.AffectedNode(); final.Affects(account) { - return true + _, final, _, _ , err:= effect.AffectedNode() + if err != nil{ + return false,err + } + if final.Affects(account) { + return true, nil } } - return false + return false, nil } func NewTransactionWithMetadata(typ TransactionType) *TransactionWithMetaData { @@ -80,7 +84,7 @@ func NewTransactionWithMetadata(typ TransactionType) *TransactionWithMetaData { // AffectedNode returns the AffectedNode, the current LedgerEntry, // the previous LedgerEntry (which might be nil) and the LedgerEntryState -func (effect *NodeEffect) AffectedNode() (*AffectedNode, LedgerEntry, LedgerEntry, LedgerEntryState) { +func (effect *NodeEffect) AffectedNode() (*AffectedNode, LedgerEntry, LedgerEntry, LedgerEntryState, error) { var ( node *AffectedNode final, previous LedgerEntry @@ -96,11 +100,11 @@ func (effect *NodeEffect) AffectedNode() (*AffectedNode, LedgerEntry, LedgerEntr case effect.ModifiedNode != nil && effect.ModifiedNode.FinalFields == nil: node, final, state = effect.ModifiedNode, LedgerEntryFactory[effect.ModifiedNode.LedgerEntryType](), Modified default: - panic(fmt.Sprintf("Unknown LedgerEntryState: %+v", effect)) + return nil, nil, nil, Created, fmt.Errorf("Unknown LedgerEntryState: %+v", effect) } previous = node.PreviousFields if previous == nil { previous = LedgerEntryFactory[final.GetLedgerEntryType()]() } - return node, final, previous, state + return node, final, previous, state, nil } diff --git a/data/orderbook.go b/data/orderbook.go index 4527711..d97309c 100644 --- a/data/orderbook.go +++ b/data/orderbook.go @@ -97,10 +97,10 @@ func defaultUint32(v *uint32) uint32 { return *v } -func (s *AccountOfferSlice) Add(offer *Offer) bool { +func (s *AccountOfferSlice) Add(offer *Offer) (bool, error) { quality, err := offer.TakerPays.Divide(offer.TakerGets) if err != nil { - panic(fmt.Sprintf("impossible quality: %s %s", offer.TakerPays, offer.TakerGets)) + return false, fmt.Errorf("impossible quality: %s %s", offer.TakerPays, offer.TakerGets) } o := AccountOffer{ Flags: LedgerEntryFlag(defaultUint32((*uint32)(offer.Flags))), @@ -114,14 +114,14 @@ func (s *AccountOfferSlice) Add(offer *Offer) bool { switch { case i == len(*s): *s = append(*s, o) - return true + return true, nil case (*s)[i].Sequence != *offer.Sequence: *s = append(*s, AccountOffer{}) copy((*s)[i+1:], (*s)[i:]) (*s)[i] = o - return true + return true, nil default: - return false + return false, nil } } diff --git a/data/proposal.go b/data/proposal.go index c299d59..3db5cac 100644 --- a/data/proposal.go +++ b/data/proposal.go @@ -1,5 +1,7 @@ package data +import "github.com/ChainSQL/go-chainsql-api/common" + type Proposal struct { Hash Hash256 LedgerHash Hash256 @@ -16,7 +18,7 @@ func (p *Proposal) GetSignature() *VariableLength { return &p.Signature } func (p *Proposal) Prefix() HashPrefix { return HP_PROPOSAL } func (p *Proposal) SigningPrefix() HashPrefix { return HP_PROPOSAL } func (p *Proposal) GetHash() *Hash256 { return &p.Hash } -func (p *Proposal) InitialiseForSigning() {} +func (p *Proposal) InitialiseForSigning(kType common.KeyType) {} func (p Proposal) SigningValues() []interface{} { return []interface{}{ @@ -27,7 +29,7 @@ func (p Proposal) SigningValues() []interface{} { } } -func (p Proposal) SuppressionId() (Hash256, error) { +func (p Proposal) SuppressionId(keyType common.KeyType) (Hash256, error) { return hashValues([]interface{}{ p.LedgerHash, p.PreviousLedger, diff --git a/data/schema.go b/data/schema.go new file mode 100644 index 0000000..03ea581 --- /dev/null +++ b/data/schema.go @@ -0,0 +1,45 @@ +package data + +type CreateSchema struct { + SchemaName string + WithState bool + SchemaAdmin string `json:"SchemaAdmin,omitempty"` + AnchorLedgerHash string `json:"AnchorLedgerHash,omitempty"` + PeerList []Peer + Validators []Validator +} + +type ModifySchema struct { + OpType uint16 + Validators []Validator + PeerList []Peer + SchemaID string +} + +type Peer struct { + Peer Endpoint +} +type PeerFormat struct { + Peer EndpointFormat +} +type Endpoint struct { + Endpoint string +} + +type EndpointFormat struct { + Endpoint VariableLength +} + +type Validator struct { + Validator PublicKeyObj +} +type ValidatorFormat struct { + Validator PublicKeyObjFormat +} +type PublicKeyObj struct { + PublicKey string +} + +type PublicKeyObjFormat struct { + PublicKey VariableLength +} diff --git a/data/signing.go b/data/signing.go index 7a641a6..4295c52 100644 --- a/data/signing.go +++ b/data/signing.go @@ -1,20 +1,23 @@ package data -import "github.com/ChainSQL/go-chainsql-api/crypto" +import ( + "github.com/ChainSQL/go-chainsql-api/common" + "github.com/ChainSQL/go-chainsql-api/crypto" +) -func Sign(s Signer, key crypto.Key, sequence *uint32) error { - s.InitialiseForSigning() +func Sign(s Signer, key crypto.Key, sequence *uint32, keyType common.KeyType) error { + s.InitialiseForSigning(key.Type()) copy(s.GetPublicKey().Bytes(), key.Public(sequence)) - hash, msg, err := SigningHash(s) + hash, msg, err := SigningHash(s, keyType) if err != nil { return err } - sig, err := crypto.Sign(key.Private(sequence), hash.Bytes(), append(s.SigningPrefix().Bytes(), msg...)) + sig, err := crypto.Sign(key, hash.Bytes(), sequence, append(s.SigningPrefix().Bytes(), msg...)) if err != nil { return err } *s.GetSignature() = VariableLength(sig) - hash, _, err = Raw(s) + hash, _, err = Raw(s,keyType) if err != nil { return err } @@ -22,8 +25,8 @@ func Sign(s Signer, key crypto.Key, sequence *uint32) error { return nil } -func CheckSignature(s Signer) (bool, error) { - hash, msg, err := SigningHash(s) +func CheckSignature(s Signer, keyType common.KeyType) (bool, error) { + hash, msg, err := SigningHash(s, keyType) if err != nil { return false, err } diff --git a/data/trade.go b/data/trade.go index 2852242..2466aa8 100644 --- a/data/trade.go +++ b/data/trade.go @@ -17,7 +17,10 @@ type Trade struct { } func newTrade(txm *TransactionWithMetaData, i int) (*Trade, error) { - _, final, previous, action := txm.MetaData.AffectedNodes[i].AffectedNode() + _, final, previous, action, err := txm.MetaData.AffectedNodes[i].AffectedNode() + if err != nil { + return nil, err + } v, ok := final.(*Offer) if !ok || action == Created { return nil, nil diff --git a/data/transaction.go b/data/transaction.go index db6a509..fd4cf8a 100644 --- a/data/transaction.go +++ b/data/transaction.go @@ -1,5 +1,7 @@ package data +import "github.com/ChainSQL/go-chainsql-api/common" + type TxBase struct { TransactionType TransactionType Flags *TransactionFlag `json:",omitempty"` @@ -194,6 +196,36 @@ type SQLStatement struct { // AutoFillField *VariableLength `json:"AutoFillField,omitempty"` } +type SchemaCreate struct { + TxBase + SchemaName VariableLength + SchemaStrategy uint8 + SchemaAdmin *Account `json:",omitempty"` + AnchorLedgerHash *Hash256 `json:",omitempty"` + Validators []ValidatorFormat + PeerList []PeerFormat +} + +type SchemaModify struct { + TxBase + OpType uint16 + Validators []ValidatorFormat + PeerList []PeerFormat + SchemaID Hash256 +} + +type SchemaDelete struct { + TxBase + SchemaID Hash256 +} + +func (txBase *TxBase) SetTxBase(seq uint32, fee Value, lastLedgerSequence *uint32, account Account) { + txBase.Sequence = seq + txBase.Fee = fee + txBase.Account = account + txBase.LastLedgerSequence = lastLedgerSequence +} + func (t *TxBase) GetBase() *TxBase { return t } func (t *TxBase) GetType() string { return txNames[t.TransactionType] } func (t *TxBase) GetTransactionType() TransactionType { return t.TransactionType } @@ -203,7 +235,8 @@ func (t *TxBase) GetSignature() *VariableLength { return t.TxnSignature } func (t *TxBase) SigningPrefix() HashPrefix { return HP_TRANSACTION_SIGN } func (t *TxBase) PathSet() PathSet { return PathSet(nil) } func (t *TxBase) GetHash() *Hash256 { return &t.Hash } - +func (t *TxBase) GetRaw() string { return "" } +func (t *TxBase) GetStatements() string { return "" } func (t *TxBase) Compare(other *TxBase) int { switch { case t.Account.Equals(other.Account): @@ -222,9 +255,15 @@ func (t *TxBase) Compare(other *TxBase) int { } } -func (t *TxBase) InitialiseForSigning() { +// func SetBase(txInterface TxInterface) { +// txInterface.SetSeq() + +// } +func (t *TxBase) InitialiseForSigning(kType common.KeyType) { if t.SigningPubKey == nil { - t.SigningPubKey = new(PublicKey) + pubkey := &PublicKey{} + pubkey.SetKey(kType) + t.SigningPubKey = pubkey } if t.TxnSignature == nil { t.TxnSignature = new(VariableLength) diff --git a/data/validation.go b/data/validation.go index 1ad51a3..d541c43 100644 --- a/data/validation.go +++ b/data/validation.go @@ -1,5 +1,9 @@ package data +import ( + "github.com/ChainSQL/go-chainsql-api/common" +) + type Validation struct { Hash Hash256 Flags uint32 @@ -21,6 +25,6 @@ func (v Validation) GetPublicKey() *PublicKey { return &v.SigningPubKey } func (v Validation) GetSignature() *VariableLength { return &v.Signature } func (v Validation) Prefix() HashPrefix { return HP_VALIDATION } func (v Validation) SigningPrefix() HashPrefix { return HP_VALIDATION } -func (v Validation) SuppressionId() (Hash256, error) { return NodeId(&v) } +func (v Validation) SuppressionId(keyType common.KeyType) (Hash256, error) { return NodeId(&v, keyType) } func (v Validation) GetHash() *Hash256 { return &v.Hash } -func (v Validation) InitialiseForSigning() {} +func (v Validation) InitialiseForSigning(kType common.KeyType) {} diff --git a/data/wire.go b/data/wire.go index b1df792..2489b54 100644 --- a/data/wire.go +++ b/data/wire.go @@ -140,7 +140,7 @@ func (a *Account) Marshal(w io.Writer) error { } func (k *PublicKey) Unmarshal(r Reader) error { - return readExpectedLength(r, k[:], "PublicKey") + return readExpectedLength(r, k.KeyValue[:], "PublicKey") } func (k *PublicKey) Marshal(w io.Writer) error { diff --git a/go.mod b/go.mod index 16a4492..d6f19cd 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,11 @@ module github.com/ChainSQL/go-chainsql-api go 1.15 require ( + github.com/ChainSQL/gm-crypto v0.0.0-20221010104745-79bcb5bd090e github.com/btcsuite/btcd v0.21.0-beta github.com/buger/jsonparser v1.1.1 github.com/gorilla/websocket v1.4.2 github.com/kr/text v0.2.0 // indirect - golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c ) diff --git a/go.sum b/go.sum index bbe8234..a1f24dc 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,6 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/ChainSQL/gm-crypto v0.0.0-20221010104745-79bcb5bd090e h1:vI/wGeAu5oQeTCGgps4RytKv5NLdxE2Y/HewQQVgVgI= +github.com/ChainSQL/gm-crypto v0.0.0-20221010104745-79bcb5bd090e/go.mod h1:Bi04CoiQyiTyK59Pzo1XZvs4aQx1mdZvwO9gwBSYkYw= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= @@ -14,19 +17,33 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -42,19 +59,42 @@ golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.15.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/net/client.go b/net/client.go index 099c4e5..12e598b 100644 --- a/net/client.go +++ b/net/client.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "log" + "strings" "sync" "time" @@ -22,7 +23,7 @@ const ReconnectInterval = 10 // Client is used to send and recv websocket msg type Client struct { cmdIDs int64 - schemaID string + SchemaID string wm *WebsocketManager sendMsgChan chan string recvMsgChan chan string @@ -44,16 +45,17 @@ func NewClient() *Client { ServerInfo: NewServerInfo(), Event: event.NewEventManager(), inited: false, + SchemaID: "", } } //Connect is used to create a websocket connection -func (c *Client) Connect(url string) error { +func (c *Client) Connect(url, tlsRootCertPath, tlsClientCertPath, tlsClientKeyPath, serverName string) error { if c.wm != nil { return c.reConnect(url) } - c.wm = NewWsClientManager(url, ReconnectInterval) + c.wm = NewWsClientManager(url, tlsRootCertPath, tlsClientCertPath, tlsClientKeyPath, serverName, ReconnectInterval) err := c.wm.Start() if err != nil { return err @@ -77,7 +79,7 @@ func (c *Client) reConnect(url string) error { c.init() } else { //connect changed,only subscribe - c.initSubscription() + c.InitSubscription() } return nil } @@ -88,13 +90,13 @@ func (c *Client) init() { go c.processMessage() go c.checkReconnection() - c.initSubscription() + c.InitSubscription() c.inited = true } func (c *Client) checkReconnection() { c.wm.OnReconnected(func() { - c.initSubscription() + c.InitSubscription() }) } @@ -102,7 +104,7 @@ func (c *Client) GetWebocketManager() *WebsocketManager { return c.wm } -func (c *Client) initSubscription() { +func (c *Client) InitSubscription() { type Subscribe struct { common.RequestBase Streams []string `json:"streams"` @@ -325,7 +327,7 @@ func (c *Client) SubscribeTx(hash string, callback export.Callback) { req := Request{} req.Command = "subscribe" req.TxHash = hash - c.asyncRequest(req) + c.syncRequest(&req) } //UnSubscribeTx subscribe a transaction by hash @@ -339,7 +341,7 @@ func (c *Client) UnSubscribeTx(hash string) { req := Request{} req.Command = "unsubscribe" req.TxHash = hash - c.asyncRequest(req) + c.syncRequest(&req) } func (c *Client) GetTableData(dataJSON interface{}, bSql bool) (string, error) { @@ -399,6 +401,9 @@ func (c *Client) GetTableData(dataJSON interface{}, bSql bool) (string, error) { } func (c *Client) syncRequest(v common.IRequest) *Request { + if c.SchemaID != "" { + v.SetSchemaID(c.SchemaID) + } data, _ := json.Marshal(v) request := NewRequest(v.GetID(), string(data)) request.Wait.Add(1) @@ -434,7 +439,200 @@ func (c *Client) sendRequest(request *Request) { c.sendMsgChan <- request.JSON } -func (c *Client) asyncRequest(v interface{}) { +func (c *Client) asyncRequest(v common.IRequest) { + if c.SchemaID != "" { + v.SetSchemaID(c.SchemaID) + } data, _ := json.Marshal(v) c.sendMsgChan <- string(data) } + +// GetServerInfo request for ServerInfo +func (c *Client) GetServerInfo() (string, error) { + type getServerInfo struct { + common.RequestBase + } + c.cmdIDs++ + accountReq := &getServerInfo{} + accountReq.ID = c.cmdIDs + accountReq.Command = "server_info" + + request := c.syncRequest(accountReq) + + err := c.parseResponseError(request) + if err != nil { + return "", err + } + + return request.Response.Value, nil +} + +func (c *Client) GetSchemaList(params string) (string, error) { + account, _ := jsonparser.GetString([]byte(params), "account") + running, _ := jsonparser.GetBoolean([]byte(params), "running") + type getRunSchemaList struct { + common.RequestBase + Account string `json:"account,omitempty"` + Running bool `json:"running"` + } + type getSchemaList struct { + common.RequestBase + Account string `json:"account,omitempty"` + } + + c.cmdIDs++ + var request *Request + if strings.Contains(params, "running") { + schemaListReq := &getRunSchemaList{} + schemaListReq.ID = c.cmdIDs + schemaListReq.Command = "schema_list" + if account != "" { + schemaListReq.Account = account + } + schemaListReq.Running = running + request = c.syncRequest(schemaListReq) + + }else{ + schemaListReq := &getSchemaList{} + schemaListReq.ID = c.cmdIDs + schemaListReq.Command = "schema_list" + if account != "" { + schemaListReq.Account = account + } + + request = c.syncRequest(schemaListReq) + } + + err := c.parseResponseError(request) + if err != nil { + return "", err + } + return request.Response.Value, nil +} +func (c *Client) GetSchemaInfo(schemaID string) (string, error) { + if schemaID == "" { + return "", fmt.Errorf("Invalid parameter") + } + type getSchemaInfo struct { + common.RequestBase + Schema string `json:"schema"` + } + c.cmdIDs++ + schemaInfoReq := &getSchemaInfo{} + schemaInfoReq.ID = c.cmdIDs + schemaInfoReq.Command = "schema_info" + schemaInfoReq.Schema = schemaID + request := c.syncRequest(schemaInfoReq) + + err := c.parseResponseError(request) + if err != nil { + return "", err + } + return request.Response.Value, nil +} + +func (c *Client) StopSchema(schemaID string) (string, error) { + if schemaID == "" { + return "", fmt.Errorf("Invalid parameter") + } + type StopSchema struct { + common.RequestBase + Schema string `json:"schema"` + } + c.cmdIDs++ + StopSchemaReq := &StopSchema{} + StopSchemaReq.ID = c.cmdIDs + StopSchemaReq.Command = "stop" + StopSchemaReq.Schema = schemaID + request := c.syncRequest(StopSchemaReq) + + err := c.parseResponseError(request) + if err != nil { + return "", err + } + return request.Response.Value, nil +} + +func (c *Client) StartSchema(schemaID string) (string, error) { + if schemaID == "" { + return "", fmt.Errorf("Invalid parameter") + } + type StartSchema struct { + common.RequestBase + Schema string `json:"schema"` + } + c.cmdIDs++ + StartSchemaReq := &StartSchema{} + StartSchemaReq.ID = c.cmdIDs + StartSchemaReq.Command = "schema_start" + StartSchemaReq.Schema = schemaID + request := c.syncRequest(StartSchemaReq) + + err := c.parseResponseError(request) + if err != nil { + return "", err + } + return request.Response.Value, nil +} + +func (c *Client) Unsubscribe() (string, error) { + type Unsubscribe struct { + common.RequestBase + Streams []string `json:"streams"` + } + c.cmdIDs++ + unsubCmd := &Unsubscribe{ + RequestBase: common.RequestBase{ + Command: "unsubscribe", + ID: c.cmdIDs, + }, + Streams: []string{"ledger", "server"}, + } + request := c.syncRequest(unsubCmd) + + err := c.parseResponseError(request) + if err != nil { + return "", err + } + return request.Response.Value, nil +} + +func (c *Client) GetTransaction(hash string) (string, error) { + type getTransaction struct { + common.RequestBase + Transaction string `json:"transaction"` + } + + c.cmdIDs++ + getTransactionReq := &getTransaction{} + getTransactionReq.ID = c.cmdIDs + getTransactionReq.Command = "tx" + getTransactionReq.Transaction = hash + request := c.syncRequest(getTransactionReq) + + err := c.parseResponseError(request) + if err != nil { + return "", err + } + return request.Response.Value, nil +} + +func (c *Client) GetTransactionResult(hash string) (string, error) { + type getTransactionResult struct { + common.RequestBase + Transaction string `json:"transaction"` + } + + c.cmdIDs++ + getTxResultReq := &getTransactionResult{} + getTxResultReq.ID = c.cmdIDs + getTxResultReq.Command = "tx_result" + getTxResultReq.Transaction = hash + request := c.syncRequest(getTxResultReq) + + err := c.parseResponseError(request) + if err != nil { + return "", err + } + return request.Response.Value, nil +} \ No newline at end of file diff --git a/net/serverinfo.go b/net/serverinfo.go index 7a6242e..0208f99 100644 --- a/net/serverinfo.go +++ b/net/serverinfo.go @@ -48,7 +48,7 @@ func (s *ServerInfo) Update(result string) { s.GetFieldInt(result, &s.TxnCount, "txn_count") // s.GetFieldString(result, &s.Ledgerhash, "ledger_hash") // s.GetFieldString(result, &s.ServerStatus, "server_status") - log.Printf("!!!!!!!!!!ServerUpdate ledger_index=%d\n", s.LedgerIndex) +// log.Printf("!!!!!!!!!!ServerUpdate ledger_index=%d\n", s.LedgerIndex) s.Updated = true } @@ -58,7 +58,7 @@ func (s *ServerInfo) GetFieldInt(result string, field *int, fieldInJSON string) if err == nil { *field = int(nValue) } else if fieldInJSON == "ledger_index" { - log.Printf("GetFieldInt error for field %s:%s\n", fieldInJSON, result) + //log.Printf("GetFieldInt error for field %s:%s\n", fieldInJSON, result) } } diff --git a/net/utility.go b/net/utility.go index 511f751..b1f496a 100644 --- a/net/utility.go +++ b/net/utility.go @@ -39,3 +39,24 @@ func PrepareTable(client *Client, name string) (uint32, string, error) { w.Wait() return seq, nameInDB, err } + +//PrepareTable return the account sequence and table NameInDB +func PrepareRipple(client *Client) (uint32, error) { + + var seq uint32 = 0 + err := error(nil) + + info, errTmp := client.GetAccountInfo(client.Auth.Address) + if errTmp != nil { + err = errTmp + return 0, errTmp + } + sequence, errTmp := jsonparser.GetInt([]byte(info), "result", "account_data", "Sequence") + if errTmp != nil { + err = errTmp + return 0, errTmp + } + seq = uint32(sequence) + + return seq, err +} diff --git a/net/websocketManager.go b/net/websocketManager.go index 7d6d423..ddb1117 100644 --- a/net/websocketManager.go +++ b/net/websocketManager.go @@ -1,6 +1,10 @@ package net import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" "log" "sync" "time" @@ -18,16 +22,21 @@ type WebsocketManager struct { sendMsgChan chan string recvMsgChan chan string isAlive bool + isClose bool timeout int // used for reconnecting muxRead *sync.Mutex muxWrite *sync.Mutex muxConnect *sync.Mutex onReconnected Reconnected first_connect bool + serverName string + tlsRootCertPath string + tlsClientKeyPath string + tlsClientCertPath string } // NewWsClientManager is a constructor -func NewWsClientManager(url string, timeout int) *WebsocketManager { +func NewWsClientManager(url, tlsRootCertPath, tlsClientCertPath, tlsClientKeyPath, serverName string, timeout int) *WebsocketManager { var sendChan = make(chan string, 1024) var recvChan = make(chan string, 1024) var conn *websocket.Conn @@ -37,26 +46,65 @@ func NewWsClientManager(url string, timeout int) *WebsocketManager { sendMsgChan: sendChan, recvMsgChan: recvChan, isAlive: false, + isClose: false, timeout: timeout, muxRead: new(sync.Mutex), muxWrite: new(sync.Mutex), muxConnect: new(sync.Mutex), onReconnected: nil, first_connect: true, + serverName: serverName, + tlsRootCertPath: tlsRootCertPath, + tlsClientKeyPath: tlsClientKeyPath, + tlsClientCertPath: tlsClientCertPath, } } // 链接服务端 func (wsc *WebsocketManager) dail() error { var err error - log.Printf("connecting to %s", wsc.url) + //log.Printf("connecting to %s", wsc.url) websocket.DefaultDialer.HandshakeTimeout = util.DIAL_TIMEOUT * time.Second - wsc.conn, _, err = websocket.DefaultDialer.Dial(wsc.url, nil) + + // tls config + tlsConfig := &tls.Config{ + MaxVersion: tls.VersionTLS12, + } + + if wsc.tlsRootCertPath != "" { + var caPem []byte + caPem, err = ioutil.ReadFile(wsc.tlsRootCertPath) + if err != nil { + return fmt.Errorf("failed to load tls root cert(path = %s), err = %v", wsc.tlsRootCertPath, err) + } + caPool := x509.NewCertPool() + if !caPool.AppendCertsFromPEM(caPem) { + return fmt.Errorf("credentials: failed to append certificates") + } + + tlsConfig.ServerName = wsc.serverName + tlsConfig.RootCAs = caPool + + if wsc.tlsClientCertPath != "" { + clientCert, err := tls.LoadX509KeyPair(wsc.tlsClientCertPath, wsc.tlsClientKeyPath) + tlsConfig.Certificates = []tls.Certificate{clientCert} + if err != nil { + return fmt.Errorf("failed to load tls client (cert path = %s; key path = %s), err = %v", wsc.tlsClientCertPath, wsc.tlsClientKeyPath, err) + } + } + + dailer := &websocket.Dialer{TLSClientConfig: tlsConfig} + wsc.conn, _, err = dailer.Dial(wsc.url, nil) + } else { + wsc.conn, _, err = websocket.DefaultDialer.Dial(wsc.url, nil) + } + if err != nil { - log.Printf("connecting to %s failed,err:%s", wsc.url, err.Error()) + //log.Printf("connecting to %s failed,err:%s", wsc.url, err.Error()) return err } wsc.isAlive = true + wsc.isClose = false log.Printf("connecting to %s success!", wsc.url) return nil } @@ -71,8 +119,11 @@ func (wsc *WebsocketManager) Disconnect() error { return err } wsc.conn = nil + close(wsc.sendMsgChan) + close(wsc.recvMsgChan) } + wsc.isClose = true wsc.isAlive = false wsc.muxConnect.Unlock() @@ -88,11 +139,16 @@ func (wsc *WebsocketManager) SetUrl(url string) { func (wsc *WebsocketManager) sendMsgThread() { go func() { for { + if wsc.isClose{ + break + } if wsc.isAlive { msg := <-wsc.sendMsgChan - if wsc.conn != nil { wsc.muxWrite.Lock() + if wsc.conn == nil || !wsc.isAlive{ + break + } // wsc.conn.SetWriteDeadline(time.Now().Add(time.Duration(wsc.timeout))) err := wsc.conn.WriteMessage(websocket.TextMessage, []byte(msg)) wsc.muxWrite.Unlock() @@ -119,11 +175,20 @@ func (wsc *WebsocketManager) OnReconnected(cb Reconnected) { func (wsc *WebsocketManager) readMsgThread() { go func() { for { + if wsc.isClose{ + break + } if wsc.conn != nil && wsc.isAlive { wsc.muxRead.Lock() + if wsc.conn == nil || !wsc.isAlive{ + break + } _, message, err := wsc.conn.ReadMessage() wsc.muxRead.Unlock() if err != nil { + if wsc.conn == nil || !wsc.isAlive{ + break + } wsc.close() log.Println("read:", err) wsc.isAlive = false @@ -150,8 +215,11 @@ func (wsc *WebsocketManager) close() { func (wsc *WebsocketManager) checkReconnect() { go func() { for { + if wsc.isClose{ + break + } if !wsc.isAlive { - log.Println("checkReconnect ws disconnected,reconnect!") + //log.Println("checkReconnect ws disconnected,reconnect!") wsc.muxConnect.Lock() err := wsc.connectAndRun() wsc.muxConnect.Unlock() @@ -198,7 +266,7 @@ func (wsc *WebsocketManager) ReadChan() chan string { } func (wsc *WebsocketManager) IsConnected() bool { - return wsc.isAlive + return wsc.isAlive && !wsc.isClose } // func main() { diff --git a/test/READ.md b/test/READ.md new file mode 100644 index 0000000..9c4d946 --- /dev/null +++ b/test/READ.md @@ -0,0 +1,8 @@ +## 编译镜像下载: + docker pull peersafes/ubuntu-server-base:golang-1.17.8-gm +## 编译: + ./build.sh +## 运行: + ./test + 注:运行环境必须是linux环境 + diff --git a/test/build.sh b/test/build.sh new file mode 100644 index 0000000..53d372b --- /dev/null +++ b/test/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash +#set -x + +docker-compose -f ./build/build.yaml run --no-deps --rm go-sdk-build diff --git a/test/build/build.yaml b/test/build/build.yaml new file mode 100644 index 0000000..e6f93a6 --- /dev/null +++ b/test/build/build.yaml @@ -0,0 +1,13 @@ +version: '3' + +services: + go-sdk-build: + container_name: go-sdk-build + image: peersafes/ubuntu-server-base:golang-1.17.8-gm + environment: + - GODEBUG=netdns=go + - GO111MODULE=off + working_dir: /opt/gopath/src/github.com/ChainSQL/go-chainsql-api/test/ + volumes: + - $GOPATH/src/github.com/ChainSQL/go-chainsql-api:/opt/gopath/src/github.com/ChainSQL/go-chainsql-api + command: go build . diff --git a/test/certs/client/client.crt b/test/certs/client/client.crt new file mode 100644 index 0000000..64175d1 --- /dev/null +++ b/test/certs/client/client.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICPDCCAeKgAwIBAgIRAL3DlaPFDf1ZUmld0fu6ONAwCgYIKoEcz1UBg3UwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNTEzMDMyNTAwWhcNMzIwNTEwMDMy +NTAwWjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEfMB0GA1UEAwwWQWRtaW5Ab3JnMS5leGFtcGxlLmNv +bTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABHalTgV4QUVHCCBLrvTZ63aNUkzc +hr+8hBHn45WDhNsWzwVexwIrb9hViu4lPpzRRKA5v6pVQYvtfyHdzy30pyqjbDBq +MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +DAYDVR0TAQH/BAIwADArBgNVHSMEJDAigCC1ICJozJDscucgrrKok+wD8UlrbAID +koYA655LGIwZSjAKBggqgRzPVQGDdQNIADBFAiBMQSjtsz1Xnn5VzMqQ+xa1TVhE +/ScqLs4zwyPcELzolQIhAK27dPZIeTsoY4gAynawWdnquQppagwatBXvYFJ7sel8 +-----END CERTIFICATE----- diff --git a/test/certs/client/client.key b/test/certs/client/client.key new file mode 100644 index 0000000..df737d7 --- /dev/null +++ b/test/certs/client/client.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgUWoKJ6ldGIICHuqV +hpEck8d55ftxey3ZLkghHIz2k2GgCgYIKoEcz1UBgi2hRANCAAR2pU4FeEFFRwgg +S6702et2jVJM3Ia/vIQR5+OVg4TbFs8FXscCK2/YVYruJT6c0USgOb+qVUGL7X8h +3c8t9Kcq +-----END PRIVATE KEY----- diff --git a/test/certs/node/server.crt b/test/certs/node/server.crt new file mode 100644 index 0000000..3d614dd --- /dev/null +++ b/test/certs/node/server.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICZzCCAg6gAwIBAgIRAIhQf7H/cE4wavCbgGrgFqwwCgYIKoEcz1UBg3UwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNTEzMDMyNTAwWhcNMzIwNTEwMDMy +NTAwWjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEfMB0GA1UEAxMWcGVlcjAub3JnMS5leGFtcGxlLmNv +bTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABPZyT2sNJcPUBEYM91dQCNwqD9HJ +ZVsuYpPHUVzw0cAbL9wWEgHW55f/dnmH68Q8IY6fo89Z5O9Xy2s/YKrdgTOjgZcw +gZQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD +AjAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAILUgImjMkOxy5yCusqiT7APxSWts +AgOShgDrnksYjBlKMCgGA1UdEQQhMB+CFnBlZXIwLm9yZzEuZXhhbXBsZS5jb22C +BXBlZXIwMAoGCCqBHM9VAYN1A0cAMEQCIBiAllL72WZqRt5OE+jxf/JwepisPeoV +/OTry40qNrbFAiBWMe1QaGItDceL1l8z6tX43P+C1JUaXodnkt4P8zER+Q== +-----END CERTIFICATE----- diff --git a/test/certs/node/server.key b/test/certs/node/server.key new file mode 100644 index 0000000..055e887 --- /dev/null +++ b/test/certs/node/server.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgKdDEY7bQbGeDffDw +TmNmJWu8qkMK5nexQHPBbc2C2vWgCgYIKoEcz1UBgi2hRANCAAT2ck9rDSXD1ARG +DPdXUAjcKg/RyWVbLmKTx1Fc8NHAGy/cFhIB1ueX/3Z5h+vEPCGOn6PPWeTvV8tr +P2Cq3YEz +-----END PRIVATE KEY----- diff --git a/test/certs/root/ca.crt b/test/certs/root/ca.crt new file mode 100644 index 0000000..0da45c0 --- /dev/null +++ b/test/certs/root/ca.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICVzCCAf2gAwIBAgIQaoOw/b1RJMntvqZzcn7k2DAKBggqgRzPVQGDdTB2MQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz +Y2Eub3JnMS5leGFtcGxlLmNvbTAeFw0yMjA1MTMwMzI1MDBaFw0zMjA1MTAwMzI1 +MDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH +Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD +VQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoEcz1UB +gi0DQgAEilxdQnIWsxFUmuQSB7GItyWO8oM0izVAFRviG3m0hYOFUlExlTvrNCnW +eYBau1fUGLYI+xS0noGnOzkS5dyCCqNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud +JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud +DgQiBCC1ICJozJDscucgrrKok+wD8UlrbAIDkoYA655LGIwZSjAKBggqgRzPVQGD +dQNIADBFAiANIAqpAKHewXkISdv5VnxUHoAs9/sVCnijDPvu17f/2QIhAKuRgnz1 +TGVAeMiFFfnKw2YEMNTaQNFRtNl73nSbsHA8 +-----END CERTIFICATE----- diff --git a/test/certs/server/server.crt b/test/certs/server/server.crt new file mode 100644 index 0000000..3d614dd --- /dev/null +++ b/test/certs/server/server.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICZzCCAg6gAwIBAgIRAIhQf7H/cE4wavCbgGrgFqwwCgYIKoEcz1UBg3UwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNTEzMDMyNTAwWhcNMzIwNTEwMDMy +NTAwWjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEfMB0GA1UEAxMWcGVlcjAub3JnMS5leGFtcGxlLmNv +bTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABPZyT2sNJcPUBEYM91dQCNwqD9HJ +ZVsuYpPHUVzw0cAbL9wWEgHW55f/dnmH68Q8IY6fo89Z5O9Xy2s/YKrdgTOjgZcw +gZQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD +AjAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAILUgImjMkOxy5yCusqiT7APxSWts +AgOShgDrnksYjBlKMCgGA1UdEQQhMB+CFnBlZXIwLm9yZzEuZXhhbXBsZS5jb22C +BXBlZXIwMAoGCCqBHM9VAYN1A0cAMEQCIBiAllL72WZqRt5OE+jxf/JwepisPeoV +/OTry40qNrbFAiBWMe1QaGItDceL1l8z6tX43P+C1JUaXodnkt4P8zER+Q== +-----END CERTIFICATE----- diff --git a/test/certs/server/server.key b/test/certs/server/server.key new file mode 100644 index 0000000..055e887 --- /dev/null +++ b/test/certs/server/server.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgKdDEY7bQbGeDffDw +TmNmJWu8qkMK5nexQHPBbc2C2vWgCgYIKoEcz1UBgi2hRANCAAT2ck9rDSXD1ARG +DPdXUAjcKg/RyWVbLmKTx1Fc8NHAGy/cFhIB1ueX/3Z5h+vEPCGOn6PPWeTvV8tr +P2Cq3YEz +-----END PRIVATE KEY----- diff --git a/test/chainsql-gm/certs/client/client.crt b/test/chainsql-gm/certs/client/client.crt new file mode 100644 index 0000000..64175d1 --- /dev/null +++ b/test/chainsql-gm/certs/client/client.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICPDCCAeKgAwIBAgIRAL3DlaPFDf1ZUmld0fu6ONAwCgYIKoEcz1UBg3UwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNTEzMDMyNTAwWhcNMzIwNTEwMDMy +NTAwWjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEfMB0GA1UEAwwWQWRtaW5Ab3JnMS5leGFtcGxlLmNv +bTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABHalTgV4QUVHCCBLrvTZ63aNUkzc +hr+8hBHn45WDhNsWzwVexwIrb9hViu4lPpzRRKA5v6pVQYvtfyHdzy30pyqjbDBq +MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +DAYDVR0TAQH/BAIwADArBgNVHSMEJDAigCC1ICJozJDscucgrrKok+wD8UlrbAID +koYA655LGIwZSjAKBggqgRzPVQGDdQNIADBFAiBMQSjtsz1Xnn5VzMqQ+xa1TVhE +/ScqLs4zwyPcELzolQIhAK27dPZIeTsoY4gAynawWdnquQppagwatBXvYFJ7sel8 +-----END CERTIFICATE----- diff --git a/test/chainsql-gm/certs/client/client.key b/test/chainsql-gm/certs/client/client.key new file mode 100644 index 0000000..df737d7 --- /dev/null +++ b/test/chainsql-gm/certs/client/client.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgUWoKJ6ldGIICHuqV +hpEck8d55ftxey3ZLkghHIz2k2GgCgYIKoEcz1UBgi2hRANCAAR2pU4FeEFFRwgg +S6702et2jVJM3Ia/vIQR5+OVg4TbFs8FXscCK2/YVYruJT6c0USgOb+qVUGL7X8h +3c8t9Kcq +-----END PRIVATE KEY----- diff --git a/test/chainsql-gm/certs/node/server.crt b/test/chainsql-gm/certs/node/server.crt new file mode 100644 index 0000000..3d614dd --- /dev/null +++ b/test/chainsql-gm/certs/node/server.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICZzCCAg6gAwIBAgIRAIhQf7H/cE4wavCbgGrgFqwwCgYIKoEcz1UBg3UwdjEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs +c2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNTEzMDMyNTAwWhcNMzIwNTEwMDMy +NTAwWjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE +BxMNU2FuIEZyYW5jaXNjbzEfMB0GA1UEAxMWcGVlcjAub3JnMS5leGFtcGxlLmNv +bTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABPZyT2sNJcPUBEYM91dQCNwqD9HJ +ZVsuYpPHUVzw0cAbL9wWEgHW55f/dnmH68Q8IY6fo89Z5O9Xy2s/YKrdgTOjgZcw +gZQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD +AjAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAILUgImjMkOxy5yCusqiT7APxSWts +AgOShgDrnksYjBlKMCgGA1UdEQQhMB+CFnBlZXIwLm9yZzEuZXhhbXBsZS5jb22C +BXBlZXIwMAoGCCqBHM9VAYN1A0cAMEQCIBiAllL72WZqRt5OE+jxf/JwepisPeoV +/OTry40qNrbFAiBWMe1QaGItDceL1l8z6tX43P+C1JUaXodnkt4P8zER+Q== +-----END CERTIFICATE----- diff --git a/test/chainsql-gm/certs/node/server.key b/test/chainsql-gm/certs/node/server.key new file mode 100644 index 0000000..055e887 --- /dev/null +++ b/test/chainsql-gm/certs/node/server.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgKdDEY7bQbGeDffDw +TmNmJWu8qkMK5nexQHPBbc2C2vWgCgYIKoEcz1UBgi2hRANCAAT2ck9rDSXD1ARG +DPdXUAjcKg/RyWVbLmKTx1Fc8NHAGy/cFhIB1ueX/3Z5h+vEPCGOn6PPWeTvV8tr +P2Cq3YEz +-----END PRIVATE KEY----- diff --git a/test/chainsql-gm/certs/root/ca.crt b/test/chainsql-gm/certs/root/ca.crt new file mode 100644 index 0000000..0da45c0 --- /dev/null +++ b/test/chainsql-gm/certs/root/ca.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICVzCCAf2gAwIBAgIQaoOw/b1RJMntvqZzcn7k2DAKBggqgRzPVQGDdTB2MQsw +CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy +YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz +Y2Eub3JnMS5leGFtcGxlLmNvbTAeFw0yMjA1MTMwMzI1MDBaFw0zMjA1MTAwMzI1 +MDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH +Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD +VQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoEcz1UB +gi0DQgAEilxdQnIWsxFUmuQSB7GItyWO8oM0izVAFRviG3m0hYOFUlExlTvrNCnW +eYBau1fUGLYI+xS0noGnOzkS5dyCCqNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud +JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud +DgQiBCC1ICJozJDscucgrrKok+wD8UlrbAIDkoYA655LGIwZSjAKBggqgRzPVQGD +dQNIADBFAiANIAqpAKHewXkISdv5VnxUHoAs9/sVCnijDPvu17f/2QIhAKuRgnz1 +TGVAeMiFFfnKw2YEMNTaQNFRtNl73nSbsHA8 +-----END CERTIFICATE----- diff --git a/test/chainsql-gm/chainsqld.cfg b/test/chainsql-gm/chainsqld.cfg new file mode 100644 index 0000000..5dfd022 --- /dev/null +++ b/test/chainsql-gm/chainsqld.cfg @@ -0,0 +1,146 @@ +[server] +port_https_admin_local +port_wss_public +port_peer + +[port_https_admin_local] +port = 5005 +ip = 0.0.0.0 +admin = 0.0.0.0 +protocol = https +#节点https服务的密钥和证书配置 +ssl_key = ./node/server.key +ssl_cert = ./node/server.crt +ssl_verify = 1 + +[port_wss_public] +port = 6006 +ip = 0.0.0.0 +admin = 0.0.0.0 +protocol = wss +#节点wss服务的密钥和证书配置 +ssl_key = ./node/server.key +ssl_cert = ./node/server.crt +ssl_verify = 1 + +[port_peer] +port = 5017 +ip = 0.0.0.0 +protocol = peer + +##节点准入的根证书配置 +#[peer_x509_root_path] +#/home/wangchao/workplace/chainsqld_peers/peer1/ca1.crt +#/home/wangchao/workplace/chainsqld_peers/peer1/ca2.crt +# +##节点准入的节点子证书配置 +#[peer_x509_cred_path] +#/home/wangchao/workplace/chainsqld_peers/peer1/peer1.crt + +#------------------------------------------------------------------------------- + +#账户证书体系的根证书配置 +#[x509_crt_path] +#./root.crt + +#------------------------------------------------------------------------------- + +[node_size] +tiny +#medium + +[node_db] +type=RocksDB +path=./data/RocksDB +open_files=2000 +filter_bits=12 +cache_mb=256 +file_size_mb=8 +file_size_mult=2 + +[ledger_history] +full + +[database_path] +./data + +[debug_logfile] +./data/debug.log + +[sntp_servers] +time.windows.com +time.apple.com +time.nist.gov +pool.ntp.org + +# Turn down default logging to save disk space in the long run. +# Valid values here are trace, debug, info, warning, error, and fatal +[rpc_startup] +{ "command" : "log_level", "severity" : "Warning" } +{ "command" : "log_level", "partition" : "Server", "severity" : "trace" } + +[ssl_verify] +0 + +[ips] + +[validation_seed] +pcL4xp1EkaDtvafHTjDEVmPUu9txadBCGMstvFzUxDmTJvFXgRX + +[validation_public_key] +pEnTgGrYumV8vicA6YuPnyYXPhtXJY3W7gUHdRF9LLDtwvNVty5pZUbNTJpjXo6V7G7K8Z6uozrvUSUyvQB2xZQ9ZrbRocog + +[validators] +pEnTgGrYumV8vicA6YuPnyYXPhtXJY3W7gUHdRF9LLDtwvNVty5pZUbNTJpjXo6V7G7K8Z6uozrvUSUyvQB2xZQ9ZrbRocog + +#[validator_list_sites] +#http://192.168.29.69:8000 +# +#[validator_list_keys] +#029d1f40fc569fff2a76417008d98936a04417db0758c8ab123dee6dbd08d79398 + +[features] +#FeeEscalation +MultiSign +Escrow + + +[consensus] +type=pop +init_time=10 + +[veto_amendments] +C6970A8B603D8778783B61C0D445C23D1633CCFAEF0D43E7DBCD1521D34BD7C3 SHAMapV2 +C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490 Tickets +1562511F573A19AE9BD103B5D6B9E01B3B46805AEC5D3C4805C902B514399146 CryptoConditions +86E83A7D2ECE3AD5FA87AB2195AE015C950469ABF0B72EAACED318F74886AE90 CryptoConditionsSuite +#3012E8230864E95A58C60FD61430D7E1B4D3353195F2981DC12B0C7C0950FFAC FlowCross +#42EEA5E28A97824821D4EF97081FE36A54E9593C6E4F20CBAE098C69D2E072DC fix1373 +#740352F2412A9909880C23A559FCECEDA3BE2126FED62FC7660D628A06927F11 Flow +#E2E6F2866106419B88C50045ACE96368558C345566AC8F2BDF5A5B5587F0E6FA fix1368 + +[governance] +#admin=zwotLHCa2EAw8As42jRLR8jBMyQnXe67Q9 +#admin=zNPZvrBoRzkhoAvesV7pZu2rAG17ezPz4Y +default_authority_enabled=0 + +#[auto_sync] +#1 +# +#[sync_db] +#type=mysql +#host=10.100.0.78 +#port=3306 +#user=root +#pass=1234 +#db=wc +#first_storage=0 +#charset=utf8 + +[workers] +8 + +[crypto_alg] +node_alg_type=gmalg + + diff --git a/test/chainsql-gm/docker-compose.yaml b/test/chainsql-gm/docker-compose.yaml new file mode 100644 index 0000000..632749a --- /dev/null +++ b/test/chainsql-gm/docker-compose.yaml @@ -0,0 +1,28 @@ +version: '2' +services: + chainsql: + container_name: chainsql + image: peersafes/chainsql:latest + restart: always + ports: + - 5005:5005 + - 6006:6006 + - 5017:5017 + ulimits: + nproc: 65535 + nofile: + soft: 65535 + hard: 65535 + volumes: + - ./certs/node:/opt/chainsql/node + - ./certs/root:/opt/chainsql/root + - /etc/localtime:/etc/localtime + - ./update:/usr/local/bin/update + - ./chainsqld.cfg:/opt/chainsql/chainsqld.cfg + + entrypoint: ["/bin/sh","-c","./chainsqld"] + logging: + driver: "json-file" + options: + max-size: "20m" + max-file: "100" diff --git a/test/chainsql-gm/update b/test/chainsql-gm/update new file mode 100644 index 0000000..aa31856 Binary files /dev/null and b/test/chainsql-gm/update differ diff --git a/test/main.go b/test/main.go index f0dd6e7..429eda5 100644 --- a/test/main.go +++ b/test/main.go @@ -17,31 +17,68 @@ type Account struct { secret string } +var root1 = Account{ + address: "zPHxWCKNZjpbQHV5DLpBy8rSR8HdXpPDzi", + secret: "xp6FwxZP1rrmPy2GDTobvHTgnZnrC", +} + +// zPHxWCKNZjpbQHV5DLpBy8rSR8HdXpPDzi +// zEdmwPS5BoEukn1ech2LHjuV6STkq3QYkM +var root = Account{ + address: "zHb9CJAWyB4zj91VRWn96DkukG4bwdtyTh", + secret: "xnoPBzXtMeMyMHUVTgbuqAfg1SUTb", +} +var user1 = Account{ + address: "zBonp9s7isAaDUPcfrFfYjNnhgeznoBHxF", + secret: "xn2FhQLRQqhKJeNhpgMzp2PGAYbdw", +} +var user2 = Account{ + address: "zKXfeKXkTtLSTkEzaJyu2cRmRBFRvTW2zc", + secret: "xhtBo8BLBZtTgc3LHnRspaFro5P4H", +} +var smRoot = Account{ + address: "zN7TwUjJ899xcvNXZkNJ8eFFv2VLKdESsj", + secret: "p97evg5Rht7ZB7DbEpVqmV3yiSBMxR3pRBKJyLcRWt7SL5gEeBb", +} +var smUser1 = Account{ + secret: "pwRdHmA4cSUKKtFyo4m2vhiiz5g6ym58Noo9dTsUU97mARNjevj", + address: "zMXMtS2C36J1p3uhTxRFWV8pEhHa8AMMSL", +} var tableName = "hello2" func main() { c := core.NewChainsql() - // err := c.Connect("ws://127.0.0.1:6006") - // log.Println("IsConnected:", c.IsConnected()) - // if err != nil { - // log.Println(err) - // return - // } + + serverName := "peer0.org1.example.com" + address := "wss://127.0.0.1:6006" + rootPath := "./certs/root/ca.crt" + clientCertPath := "./certs/client/client.crt" + clientKeyPath := "./certs/client/client.key" + + serverName = "" + rootPath = "" + clientCertPath = "" + clientKeyPath = "" + + err := c.Connect(address, rootPath, clientCertPath, clientKeyPath, serverName) + log.Println("IsConnected:", c.IsConnected()) + if err != nil { + log.Println(err) + return + } // var root = Account{ // address: "zHb9CJAWyB4zj91VRWn96DkukG4bwdtyTh", // secret: "xnoPBzXtMeMyMHUVTgbuqAfg1SUTb", // } - // var user = Account{ - // address: "zBonp9s7isAaDUPcfrFfYjNnhgeznoBHxF", - // secret: "xn2FhQLRQqhKJeNhpgMzp2PGAYbdw", - // } - // c.As(user.address, user.secret) // c.As(root.address, root.secret) + c.As(smRoot.address, smRoot.secret) + //c.SetSchema("44C2C733C17335C11B01BCB0B55340EA422F37307188FF84E6127F8BEBBF0C60") + //GenerateKey(rand.Reader) // c.Use(root.address) // // testSubLedger(c) - testGenerateAccount(c) - // testInsert(c) + //testGenerateAccount(c) + //testInsert(c) // testGetLedger(c) // testSignPlainText(c) @@ -49,13 +86,29 @@ func main() { // testGetBySqlUser(c) // testWebsocket() - // testTickerGet(c) + // testTickerGet(c)\ + //testValidationCreate(c) + //testGetAccountInfo(c) + testGetServerInfo(c) + // testPay(c) + //testSchemaCreate(c) //创建子链 + //testSchemaModify(c) // 修改子链 + //testGetSchemaList(c) //获取子链列表 + //testGetSchemaInfo(c) //依据子链id获取子链信息 + //testStopSchema(c) // + //testStartSchema(c) + + //testGetTransaction(c) + //testGetSchemaId(c) + //testGenerateAddress(c) + //testDeleteSchema(c) + // testGetTransactionResult(c) for { time.Sleep(time.Second * 10) } } -func testGenerateAccount(c *core.Chainsql) { +/*func testGenerateAccount(c *core.Chainsql) { accStr, err := c.GenerateAccount() if err != nil { log.Println(err) @@ -71,11 +124,11 @@ func testGenerateAccount(c *core.Chainsql) { return } log.Println(accStr) -} +}*/ func testInsert(c *core.Chainsql) { var data = []byte(`[{"id":1,"name":"echo","age":18}]`) - ret := c.Table(tableName).Insert(string(data)).Submit("db_success") + ret := c.Table("gmTest50").Insert(string(data)).Submit("db_success") log.Println(ret) } @@ -206,3 +259,121 @@ func testTickerGet(c *core.Chainsql) { ticker.Stop() done <- true } + +func testValidationCreate(c *core.Chainsql) { + seedKey, err := c.ValidationCreate() + if err != nil { + log.Println(err) + } + log.Printf("seedKey %s\n", seedKey) +} + +func testGetAccountInfo(c *core.Chainsql) { + account, err := c.GetAccountInfo(user1.address) + if err != nil { + log.Println(err) + } + log.Printf("seedKey %s\n", account) +} + +func testGetServerInfo(c *core.Chainsql) { + serverInfo, err := c.GetServerInfo() + if err != nil { + log.Println(err) + } + log.Printf("seedKey %s\n", serverInfo) +} + +func testPay(c *core.Chainsql) { + ret := c.Pay(user2.address, 3000000).Submit("validate_success") + log.Println(ret) +} + +func testSchemaCreate(c *core.Chainsql) { + schemaInfo := "{\"SchemaName\":\"hello\",\"WithState\":true,\"SchemaAdmin\":\"zHb9CJAWyB4zj91VRWn96DkukG4bwdtyTh\",\"Validators\":[{\"Validator\":{\"PublicKey\":\"02E273A1B6C5D8427F60F490FC8E03D52F35D1A57B8755E19DB0F3B683D9A81239\"}},{\"Validator\":{\"PublicKey\":\"03946B1514971B645F22EE9C96843C5705D388D65C563B7DDEB8B56E29A5283D3C\"}},{\"Validator\":{\"PublicKey\":\"026C3AB1DE848906C5F42316D2B92C3382EEE68FC08F738A2BE9D8C0BC4954936D\"}},{\"Validator\":{\"PublicKey\":\"030F9602B680A71D962111CC3EF9D27601EB9FEC7C3BA24BB4323D94C3A1CF9A04\"}}],\"PeerList\":[{\"Peer\":{\"Endpoint\":\"10.100.0.78:25413\"}},{\"Peer\":{\"Endpoint\":\"10.100.0.78:25414\"}},{\"Peer\":{\"Endpoint\":\"10.100.0.78:25415\"}},{\"Peer\":{\"Endpoint\":\"10.100.0.104:5510\"}}]}" + //schemaInfo := "{"SchemaName":"子链1","WithState":false,"SchemaAdmin":"zKTqp9kqJBag59YGmL7imH9RfukG6qVtfS","Validators":[{"Validator":{"PublicKey":"037B2D1B1C97A996B44A2FA25765DE5D937247840C960AC6E84D0E3AA8A718F96E"}},{"Validator":{"PublicKey":"038C4245389C8AB8C7665CA4002AEE75EF5D7EEB51A4410D48797BC74F275E9CC3"}},{"Validator":{"PublicKey":"0237788307F53E50D9F799F0D0ABD48258BC41D9418638BD51C481D1848E005443"}}],"PeerList":[{"Peer":{"Endpoint":"192.168.0.242:12260"}},{"Peer":{"Endpoint":"192.168.0.242:12264"}},{"Peer":{"Endpoint":"192.168.0.242:12269"}}]}" + //schemaInfo := "{\"SchemaName\":\"hello\",\"WithState\":true,\"SchemaAdmin\":\"zN7TwUjJ899xcvNXZkNJ8eFFv2VLKdESsj\",\"Validators\":[{\"Validator\":{\"PublicKey\":\"47F7288B41B45F49342FAC6B65EC529B5ED52F3DDD35140C53BB54A3A7D03F3E9166B0FD574F098F2F9E30526EC8293CE95D4956AD8EC02B34060F0709DCDEA3C5\"}},{\"Validator\":{\"PublicKey\":\"47594A1F76382A89A811B485E3B3414F18967C55A9A2BB90DF7EF36FFF5FDCB915B9C495D66ADEA79DAD97C897596F6FE093C7CDADF90BDD0C91B99D8D014C1B05\"}},{\"Validator\":{\"PublicKey\":\"47C45A7D125E49FDFF1DE6C08F738122FFDC7171E0F5AFA794D02198E35F7F1B1F07CE271CDBF9BA4DB94AA087BE4F59F2A15A60868BE4ACFA86D13B448CD06038\"}}],\"PeerList\":[{\"Peer\":{\"Endpoint\":\"192.168.177.109:5432\"}},{\"Peer\":{\"Endpoint\":\"192.168.177.109:5433\"}},{\"Peer\":{\"Endpoint\":\"192.168.177.109:5441\"}}]}" + ret := c.CreateSchema(schemaInfo).Submit("validate_success") + log.Println(ret) +} + +func testSchemaModify(c *core.Chainsql) { + schemaInfo := "{\"SchemaID\":\"2A4C77CF90F1EE9495733D95549B6E0C2ECD61A49343D04C75FE2FD366366A13\",\"Validators\":[{\"Validator\":{\"PublicKey\":\"471D5247096A08552746B5E321E925639A43D6A3ED5F48E48C678E1630F6B92F88EBE20579DCEF85371C43D7305787CAA9AADF7D705BDD1523BBCCF9865FEB34A4\"}}],\"PeerList\":[{\"Peer\":{\"Endpoint\":\"10.100.0.104:5410\"}}]}" + //schemaInfo := "{\"SchemaName\":\"hello\",\"WithState\":false,\"SchemaAdmin\":\"zBonp9s7isAaDUPcfrFfYjNnhgeznoBHxF\",\"Validators\":\"fhfhhfhfhfhfh\",\"PeerList\":[{\"Peer\":{\"Endpoint\":\"127.0.0.1:15125\"}},{\"Peer\":{\"Endpoint\":\"127.0.0.1:25125\"}},{\"Peer\":{\"Endpoint\":\"127.0.0.1:35125\"}}]}" + ret := c.ModifySchema("schema_add", schemaInfo).Submit("validate_success") + log.Println(ret) +} + +func testGetSchemaList(c *core.Chainsql) { + //param := "{\"running\":false}" + param := "" + ret, err := c.GetSchemaList(param) + log.Println(ret) + log.Println(err) +} + +func testGetSchemaInfo(c *core.Chainsql) { + schemaID := "44C2C733C17335C11B01BCB0B55340EA422F37307188FF84E6127F8BEBBF0C60" + ret, err := c.GetSchemaInfo(schemaID) + log.Println(ret) + log.Println(err) +} + +func testStopSchema(c *core.Chainsql) { + schemaID := "2A4C77CF90F1EE9495733D95549B6E0C2ECD61A49343D04C75FE2FD366366A13" + ret, err := c.StopSchema(schemaID) + log.Println(ret) + log.Println(err) +} + +func testStartSchema(c *core.Chainsql) { + schemaID := "2A4C77CF90F1EE9495733D95549B6E0C2ECD61A49343D04C75FE2FD366366A13" + ret, err := c.StartSchema(schemaID) + log.Println(ret) + log.Println(err) +} + +func testGetTransaction(c *core.Chainsql) { + txHash := "52F7B8FEBC0FEDB56AAA26FA3A8F8C3D507C2E0706BF522644B308AD0190DB88" + ret, err := c.GetTransaction(txHash) + log.Println(ret) + log.Println(err) +} + +func testGetSchemaId(c *core.Chainsql) { + txHash := "1E1EA9E9936574D17646EE9801B72B106DB35D13923FE4357746AD2DD2135C78" + ret, err := c.GetSchemaId(txHash) + log.Println(ret) + log.Println(err) +} + +func testGenerateAddress(c *core.Chainsql) { + //option := "" + option := "{\"algorithm\":\"softGMAlg\", \"secret\":\"pwRdHmA4cSUKKtFyo4m2vhiiz5g6ym58Noo9dTsUU97mARNjevj\"}" + //xp6FwxZP1rrmPy2GDTobvHTgnZnrC + //xnoPBzXtMeMyMHUVTgbuqAfg1SUTb + //option := "{\"algorithm\":\"secp256k1\", \"secret\":\"xp6FwxZP1rrmPy2GDTobvHTgnZnrC\"}" + ret, err := c.GenerateAddress(option) + if err != nil { + log.Println(err) + } else { + log.Println(ret) + } +} + +func testDeleteSchema(c *core.Chainsql) { + schemaID := "362C1B00328F08A3CE093FE64B0BC88951D364DC6D2B44601268E7F273354B4A" + ret := c.DeleteSchema(schemaID).Submit("validate_success") + log.Println(ret) +} + +func testGetTransactionResult(c *core.Chainsql) { + txHash := "48AF80C9169790BE33CBD8C5F32151C9D4483D855B195D188854636EB6551AF5" + ret, err := c.GetTransactionResult(txHash) + if err != nil { + log.Println(err) + } else { + // {"id":2,"result":{"ledger_index":28,"transaction_result":"tesSUCCESS","tx_hash":"48AF80C9169790BE33CBD8C5F32151C9D4483D855B195D188854636EB6551AF5","tx_status":"validated"},"status":"success","type":"response"} + log.Println(ret) + } +} diff --git a/util/define.go b/util/define.go index cb34cba..dd323ca 100644 --- a/util/define.go +++ b/util/define.go @@ -31,3 +31,16 @@ const ( REQUEST_TIMEOUT = 5 DIAL_TIMEOUT = 2 ) + +const ( + SchemaAdd = "schema_add" + SchemaDel = "schema_del" +) +const ( + OpTypeSchemaAdd = 1 + OpTypeSchemaDel = 2 +) + +const ( + Seqinterval = 20 +) \ No newline at end of file diff --git a/util/util.go b/util/util.go index 080fbea..8dd92f7 100644 --- a/util/util.go +++ b/util/util.go @@ -35,11 +35,9 @@ func SignPlainData(privateKey string, data string) (string, error) { return "", err } sequenceZero := uint32(0) - private := key.Private(&sequenceZero) hash := crypto.Sha512Half([]byte(data)) - sigBytes, err := crypto.Sign(private, hash, nil) + sigBytes, err := crypto.Sign(key, hash, &sequenceZero, nil) if err != nil { - log.Println(err) return "", err } return crypto.B2H(sigBytes), nil