Golang smart contract issue during invoking - go

Facing an issue in golang smart contract, while invoking chaincode create function i am getting an error of argument.
Whenever I'm going to send a string of array as an argument in Chain-code function. I'm getting an issue.
here I'm attaching my function implementation.
func (m *MdmChaincode) CreateSeqMrNum(ctx contractapi.TransactionContextInterface, args []string) error {
SeqId := args [0]
SrNo := args [1]
DocType := args [2]
mtrSeqNo := &SeqMrNum{SeqId, SrNo, DocType}
seqMrNumAsBytes, err := json.Marshal(mtrSeqNo)
if err != nil {
return fmt.Errorf("Unable to marshal the JSON.")
}
err = ctx.GetStub().PutState(SeqId, seqMrNumAsBytes)
if err != nil {
return fmt.Errorf("Cannot add to World State: %s", err.Error())
}
return nil
}
Error: endorsement failure during invoke. response: status:500 message: "Error managing parameter param0. Conversion error. Value 'M1001' not passed in expected format []string.
Facing an issue in golang smart contract, while invoking chaincode create function I am getting an error of argument.
Whenever I'm going to send a string of array as an argument in Chain-code function. I'm getting an issue.
here I'm attaching my function implementation.

It seems like your transaction function implementation is expecting the client to pass a single argument, which is a slice of strings. How well this is supported, I am not sure. If it is, I think the contract runtime will be expecting the client to format that single argument as a JSON array of strings.
It might be easier to accept each piece of information as a separate parameter:
func (m *MdmChaincode) CreateSeqMrNum(
ctx contractapi.TransactionContextInterface,
seqID string,
srNo string,
docType string
) error {
...
}
and then have your client submit a transaction with those three distinct arguments:
contract.Submit("CreateSeqMrNum", client.WithArguments(seqID, srNo, docType))
Alternatively, if you want the client to pass a JSON (or some other format) parameter containing all the required information, you could accept a single string parameter that you then explicitly deserialise within the smart contract.

Related

Why don't I see fmt logs in my terminal when running go app locally?

I'm trying to debug my golang app. Currently, I have an API request that isn't working which has this line of code:
fmt.Errorf("Object(%q).CopierFrom(%q).Run: %v", dstName, object, err)
How can I view the output of this error log? And if it's not possible what are some other ways to debug in go? (runtime invocation would be nice)
fmt.Errorf() creates an error object. but not print.doc
If you're just trying to print the message to stdout:
run
package main
import (
"fmt"
)
func main() {
const name, id = "bueller", 17
err := fmt.Errorf("user %q (id %d) not found", name, id)
fmt.Println(err.Error())
}
out:
user "bueller" (id 17) not found
if you want debug golang code, I recommend use log packages for example:
zerolog
package main
import (
"errors"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
// UNIX Time is faster and smaller than most timestamps
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
err := errors.New("seems we have an error here")
log.Error().Err(err).Msg("this is an error")
}
out:
{"level":"error","error":"seems we have an error here","time":1640795128,"message":"this is an error"}
fmt.Errorf creates an error object; it does not print.
From the docs for fmt.Errorf:
func Errorf(format string, a ...interface{}) error
If you're just trying to print the message to stdout:
fmt.Printf("Object(%q).CopierFrom(%q).Run: %v\n", dstName, object, err)
If you want to write to an error log, I recommend looking at the log package. For example, if you were looking to write to stderr:
logger := log.New(os.Stderr, "my-app", 0)
logger.Printf("Object(%q).CopierFrom(%q).Run: %v", dstName, object, err)
fmt.Errorf creates an error - ideal for function returns - but it's not implicitly logged.
If you want to log an error simply:
log.Printf("api X: error %v", err)
It is better to read the function signature and comments before you use any functions.
// Errorf formats according to a format specifier and returns the string as a
// value that satisfies error.
//
// If the format specifier includes a %w verb with an error operand,
// the returned error will implement an Unwrap method returning the operand. It is
// invalid to include more than one %w verb or to supply it with an operand
// that does not implement the error interface. The %w verb is otherwise
// a synonym for %v.
func Errorf(format string, a ...interface{}) error

ERR wrong number of arguments for 'zadd' command

I have found this Error:
ERR wrong number of arguments for 'zadd' command in golang.
This is my code:
defaultPriority:type String
mb.MessageID:type string
mb.EndpointID: type string
_, err = mbDal.redisClient.ZAdd(mb.EndpointID, redis.Z{Score: defaultPriority, Member: mb.MessageID})
if err != nil {
return fmt.Errorf("failed to add mailbox id %s in redis; error %v", mb.MessageID, err)
}
How can I fix this error message?
zadd is used in go-redis/redis, and is defined here
// Redis `ZADD key score member [score member ...]` command.
func (c cmdable) ZAdd(key string, members ...*Z) *IntCmd {
Double-check your go.mod dependencies list.
10 months ago, in go-redis v7 (instead of current v8), the signature for that function was:
func (c *cmdable) ZAdd(key string, members ...Z) *IntCmd {
It used Z instead of (today) *Z.
In your case, you should pass:
&redis.Z{Score: defaultPriority, Member: mb.MessageID}
I was trying to insert redis.Z{Score: [an int value], Member: code} to Redis sorted set and it failed with that error.
So I checked my logic and find out someone calling my method with code as an empty string. in my case first insert was successful but after that, all insert failed with that error.
I'm using github.com/go-redis/redis v6.15.6

Why can't I use conn.ok() from net.go?

I'm coming at Golang from a Python background and I am trying to wrap my head around various new concepts.
One thing I have come across is this function in net.go:
func (c *conn) ok() bool { return c != nil && c.fd != nil }
This function is called by multiple net.go methods, e.g. conn.Read:
// Read implements the Conn Read method.
func (c *conn) Read(b []byte) (int, error) {
if !c.ok() {
return 0, syscall.EINVAL
}
I am trying to understand how the ok() method can be called on conn, despite the fact that ok() does not appear to be an interface of conn.
Certainly I do not seem to be able to call ok() from my client code:
func main() {
conn, err := net.Dial("tcp", "www.reddit.com:80")
if err != nil {
os.Exit(-1)
}
fmt.Println(&conn.ok())
}
Output:
./server.go:14:22: conn.ok undefined (type net.Conn has no field or method ok)
Any pointers appreciated...
From Go document :
An identifier may be exported to permit access to it from another
package. An identifier is exported if the first character of the
identifier's name is a Unicode upper case letter
So , ok function is not exported and you can't access it outside of net package.
Go does not use public/private keywords for visibility of an identifier. If the initial character is an upper case letter, the identifier is exported(public); otherwise it is not:
upper case initial letter: Name is visible to clients of package
otherwise: name (or _Name) is not visible to clients of package
There is no field or method like ok in net.Conn that what the error says and that is correct.
when you try to read and write into the conn , you would get err and number of bytes read or write it into the connection.

Using empty interfaces in go

I am trying to understand the code that is used at my company. I am new to go lang, and I have already gone through the tutorial on their official website. However, I am having a hard time wrapping my head around empty interfaces, i.e. interface{}. From various sources online, I figured out that the empty interface can hold any type. But, I am having a hard time figuring out the codebase, especially some of the functions. I will not be posting the entire thing here, but just the minimal functions in which it has been used. Please bear with me!
Function (I am trying to understand):
func (this *RequestHandler) CreateAppHandler(rw http.ResponseWriter, r *http.Request) *foo.ResponseError {
var data *views.Data = &views.Data{Attributes: &domain.Application{}}
var request *views.Request = &views.Request{Data: data}
if err := json.NewDecoder(r.Body).Decode(request); err != nil {
logrus.Error(err)
return foo.NewResponsePropogateError(foo.STATUS_400, err)
}
requestApp := request.Data.Attributes.(*domain.Application)
requestApp.CreatedBy = user
Setting some context, RequestHandler is a struct defined in the same package as this code. domain and views are seperate packages. Application is a struct in the package domain. The following two structs are part of the package views:
type Data struct {
Id string `json:"id"`
Type string `json:"type"`
Attributes interface{} `json:"attributes"`
}
type Request struct {
Data *Data `json:"data"`
}
The following are part of the package json:
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
func (dec *Decoder) Decode(v interface{}) error {
if dec.err != nil {
return dec.err
}
if err := dec.tokenPrepareForDecode(); err != nil {
return err
}
if !dec.tokenValueAllowed() {
return &SyntaxError{msg: "not at beginning of value"}
}
// Read whole value into buffer.
n, err := dec.readValue()
if err != nil {
return err
}
dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
dec.scanp += n
// Don't save err from unmarshal into dec.err:
// the connection is still usable since we read a complete JSON
// object from it before the error happened.
err = dec.d.unmarshal(v)
// fixup token streaming state
dec.tokenValueEnd()
return err
}
type Decoder struct {
r io.Reader
buf []byte
d decodeState
scanp int // start of unread data in buf
scan scanner
err error
tokenState int
tokenStack []int
}
Now, I understood that, in the struct Data in package views, Application is being set as a type for the empty interface. After that, a pointer to Request in the same package is created which points to the variable data.
I have the following doubts:
What exactly does this keyword mean in Go? What is the purpose of writing this * RequestHandler?
Initialization of a structure in Go can be done while assigning it to a variable by specifying the values of all it's members. However, here, for the struct Data, only the empty interface value is assigned and the values for the other two fields are not assigned?
What is the advantage of assigning the Application struct to an empty interface? Does it mean I can use the struct members using the interface variable directly?
Can someone help me figure out the meaning of this statement? json.NewDecoder(r.Body).Decode(request)?
While I know this is too much, but I am having a hard time figuring out the meaning of interfaces in Go. Please help!
this is not a keyword in go; any variable name can be used there. That is called the receiver. A function declared in that way must be called like thing.func(params), where "thing" is an expression of the type of the receiver. Within the function, the receiver is set to the value of thing.
A struct literal does not have to contain values for all the fields (or any of them). Any fields not explicitly set will have the zero value for their types.
As you said, an empty interface can take on a value of any type. To use a value of type interface{}, you would use type assertion or a type switch to determine the type of the value, or you could use reflection to use the value without having to have code for the specific type.
What specifically about that statement do you not understand? json is the name of a package in which the function NewDecoder is declared. That function is called, and then the Decode function (which is implemented by the type of the return value of NewDecoder) is called on that return value.
You may want to take a look at Effective Go and/or The Go Programming Language Specification for more information.

Save error in database Golang

I'm running http request in golang
resp, err := client.Do(req)
if err != nil {
return "", err
}
So, it returns error back to the main function, that attempts to store it in the database:
_, err = db.Exec("UPDATE test SET error = $1 WHERE id = $2", error, id)
I receive the following error: sql: converting Exec argument #1's type: unsupported type errors.errorString, a struct exit status 1
So, I understand, that error has a different type, but I can't find information on how to pass the value of the error to the string. Could someone direct me in a right way.
Use the function:
error.Error()
to get a string representation of the error.
Tip: avoid naming variables with existing type names. error is a type name and it's also your variable name, which might lead to confusion.

Resources