fabric-samples
fabric-samples copied to clipboard
failed to submit transaction: rpc error: code = Aborted desc = failed to endorse transaction
After execute the sample of asset-transfer-basic.
I try to write my own smart contract, deploy it and invoke it.
I wrote my own contract code imitating asset-transfer.
package chaincode
import(
"encoding/json"
"fmt"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)
// SmartContract用于管理TEE相关信息
type SmartContract struct {
contractapi.Contract
}
type TEEInfo struct {
ID String `json:"ID"`
PublicKey String `json:"PublicKey"`
TEECert String `json:"TEECert"`
}
// InitInfo adds an example of TEEInfo to the list
func (s *SmartContract) InitInfo (ctx contractapi.TransactionContextInterface) error {
infos := []Info{
{ID: "Info1", PublicKey: "PK1", TEECert: "Cert1"},
{ID: "Info2", PublicKey: "PK2", TEECert: "Cert2"},
}
for _, info := range infos {
infoJSON, err := json.Marshal(info)
if err != nil{
return err
}
err = ctx.GetStub().PutState(info.ID, InfoJSON)
if err != nil{
return fmt.Errorf("failed to put to world state. %v", err)
}
}
return nil
}
func (s *SmartContract) InsertInfo(ctx contractapi.TransactionContextInterface, id string, publicKey string, teeCert string) error {
exists, err := s.InfoExists(ctx, id)
if err != nil {
return err
}
if exists{
return fmt.Errorf("the info %s already exists", id)
}
info := Info{
ID: id,
PublicKey: publicKey,
TEECert: teeCert,
}
infoJSON, err := json.Marshal(info)
if err != nil {
return err
}
return ctx.GetStub.PutState(id, infoJSON)
}
func (s *SmartContract) InfoExists(ctx contractapi.TransactionContextInterface, id string) (bool, error){
infoJSON, err := ctx.GetStub().GetState(id)
if err != nil{
return false, fmt.Errorf("failed to read from world state: %v", err)
}
return infoJSON != nil, nil
}
And I deploy it successfully.
I try to use gateway
to communicate with blockchain.
the code is same like asset-transfer.
package main
import (
//"bytes"
//"context"
"crypto/x509"
//"encoding/json"
//"errors"
"fmt"
"github.com/hyperledger/fabric-gateway/pkg/client"
"github.com/hyperledger/fabric-gateway/pkg/identity"
//gwproto "github.com/hyperledger/fabric-protos-go/gateway"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
//"google.golang.org/grpc/status"
"io/ioutil"
"log"
"path"
"time"
)
const (
mspID = "Org1MSP"
cryptoPath = "../../test-network/organizations/peerOrganizations/org1.example.com"
certPath = cryptoPath + "/users/[email protected]/msp/signcerts/cert.pem"
keyPath = cryptoPath + "/users/[email protected]/msp/keystore/"
tlsCertPath = cryptoPath + "/peers/peer0.org1.example.com/tls/ca.crt"
peerEndpoint = "localhost:7051"
gatewayPeer = "peer0.org1.example.com"
channelName = "mychannel"
chaincodeName = "teecontract"
)
var now = time.Now()
var Id = fmt.Sprintf("asset%d", now.Unix()*1e3+int64(now.Nanosecond())/1e6)
func main() {
log.Println("============ application-golang starts ============")
// The gRPC client connection should be shared by all Gateway connections to this endpoint
clientConnection := newGrpcConnection()
defer clientConnection.Close()
id := newIdentity()
sign := newSign()
// Create a Gateway connection for a specific client identity
gateway, err := client.Connect(
id,
client.WithSign(sign),
client.WithClientConnection(clientConnection),
// Default timeouts for different gRPC calls
client.WithEvaluateTimeout(5*time.Second),
client.WithEndorseTimeout(15*time.Second),
client.WithSubmitTimeout(5*time.Second),
client.WithCommitStatusTimeout(1*time.Minute),
)
if err != nil {
panic(err)
}
defer gateway.Close()
network := gateway.GetNetwork(channelName)
contract := network.GetContract(chaincodeName)
fmt.Println("initLedger:")
initLedger(contract)
log.Println("============ application-golang ends ============")
}
// newGrpcConnection creates a gRPC connection to the Gateway server.
func newGrpcConnection() *grpc.ClientConn {
certificate, err := loadCertificate(tlsCertPath)
if err != nil {
panic(err)
}
certPool := x509.NewCertPool()
certPool.AddCert(certificate)
transportCredentials := credentials.NewClientTLSFromCert(certPool, gatewayPeer)
connection, err := grpc.Dial(peerEndpoint, grpc.WithTransportCredentials(transportCredentials))
if err != nil {
panic(fmt.Errorf("failed to create gRPC connection: %w", err))
}
return connection
}
// newIdentity creates a client identity for this Gateway connection using an X.509 certificate.
func newIdentity() *identity.X509Identity {
certificate, err := loadCertificate(certPath)
if err != nil {
panic(err)
}
id, err := identity.NewX509Identity(mspID, certificate)
if err != nil {
panic(err)
}
return id
}
func loadCertificate(filename string) (*x509.Certificate, error) {
certificatePEM, err := ioutil.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("failed to read certificate file: %w", err)
}
return identity.CertificateFromPEM(certificatePEM)
}
// newSign creates a function that generates a digital signature from a message digest using a private key.
func newSign() identity.Sign {
files, err := ioutil.ReadDir(keyPath)
if err != nil {
panic(fmt.Errorf("failed to read private key directory: %w", err))
}
privateKeyPEM, err := ioutil.ReadFile(path.Join(keyPath, files[0].Name()))
if err != nil {
panic(fmt.Errorf("failed to read private key file: %w", err))
}
privateKey, err := identity.PrivateKeyFromPEM(privateKeyPEM)
if err != nil {
panic(err)
}
sign, err := identity.NewPrivateKeySign(privateKey)
if err != nil {
panic(err)
}
return sign
}
func initLedger(contract *client.Contract) {
fmt.Printf("Submit Transaction: InitLedger, function creates the initial set of assets on the ledger \n")
_, err := contract.SubmitTransaction("InitInfo")
if err != nil {
panic(fmt.Errorf("failed to submit transaction: %w", err))
}
fmt.Printf("*** Transaction committed successfully\n")
}
But when I run go run .
under the application -gateway-go. it report
Anyone else know why. It seems like the command
contract.SubmitTransaction("InitInfo")
get wrong. but I don't know why and how I can fix it. :(