How to get the value corresponding to solidity "tx.origin" in substrate ink? - substrate

I'm implementing a contract that calls contract B from contract A.
Now alice called contract B through contract A. I would like to know that it was alice who called this contract B. Can I get it?
let caller = self.env().caller();
If you get caller in contract B like above, its value will be the contract address of contract A.
tx.origin
I would like to get a value similar to solidity's "tx.origin".Is it possible?

This function does not exist in ink!. Reason is that is considered unsafe and its addition a mistake in Solidity.

Related

How can I get the transaction hash from a contract call (AssemblyScript)?

I want to be able to return the transaction hash in some of my contract methods using near-sdk-as. I thought I could use context.blockIndex, but I assume this is something other than the transaction hash?
You can't return tx hash from the contract method because the transaction is not finished at that point, you're still in it
the contract call itself, the one you make from any client, receives the transaction hash as part id the response value
see here for an example
https://github.com/Learn-NEAR/starter--near-api-js/blob/ffe12359f94aa8b558824a3f3ec1f4ba82c0e86a/contract-advanced.html#L54

Is it a good practice to add repository to a DTO class?

I have a DTO object, it needs EntityA from DB for conversion to EntityB. Where should the convertion be done?
Is it a good practice to have a static method right in DTO class and a repository instance to load an object?
I do appreciate your answer!
The law of Demeter is about reducing coupling by minimizing the things an object talks to. Here the method needs an A to make a B, so let it take A as a parameter. The Repository that retrieves As is one step removed, and should be left out.
The usual analogy is that when I go to pay a cashier for something I take the money or credit card out of my wallet and give it to them, I don’t hand them my wallet and let them dig around in it.

Using msgp with interfaces and maps in Go

I have a map that uses an interface as the key. The map is defined like this MyMap map[Signature]Packets. The interface is Signature, and there will be two structs A and B that implement this interface. I am also using msgp to serialize these two structs.
My issue is that msgp automatically generates methods that use a pointer as the type of the function receiver, which I think will make the key Signature receive pointers. If that was the case, then the key would be different every single time since pointers are different, even though the underlying values are the same. So, every time, I would be creating a new entry instead of finding the existing one and modifying it.
I wonder:
Is there a way to force msgp to generate methods purely with function receivers of the concrete type? Currently, I can only modify the function receivers of auto-generated methods like MarshalMsg and UnmarshalMsg to the concrete type (A or B instead of *A or *B). By doing that, the key of the map is either of type A or of type B, and the map MyMap works fine. However, I know I should not modify the auto-generated code. So, I wonder whether there is an acceptable way to do that.
If there is no way to do 1., is there any workaround to solve this problem? I really need some polymorphic feature of the map's key with the use of msgp.
UPDATE 1 (Apr. 12):
Thanks for sharing your thoughts and offering solutions. Here are some details about my question.
The background is that the map is used for collecting different network events. The two structs implementing the interface Signature are EventSignatureIPv4 and EventSignatureIPv6
type EventSignatureIPv4 struct {
SourceIPv4 [4]byte
Port uint16
Traffic TrafficType
}
type EventSignatureIPv6 struct {
SourceIPv6 [16]byte
Port uint16
Traffic TrafficType
}
and Signature is holding common methods shared between IPv4 and IPv6 data. So, essentially, I want to collect and group corresponding IPv4/v6 events at the runtime. The key of the map is to identify the same source, and the value of the map is to collect events with different destinations.
The msgp library I am using is this one https://pkg.go.dev/github.com/tinylib/msgp#v1.1.5/msgp
Correct me if I am wrong. For compositions in Go, if one of the methods in the method set has a function receiver of the pointer type, then the instance would only be of the pointer type? So here, as I have
func (z *EventSignatureIPv6) MarshalMsg(b []byte) (o []byte, err error) {
/* Auto-generated code */
}
whenever I use Signature to receive the struct EventSignatureIPv6, the struct would only be of type *EventSignatureIPv6?
You are right, "two pointer values are equal if they point to the same variable.", so if you are looking to compare interfaces that may hold pointers to different types, e.g. *A and *B, you are already in trouble.
With that said, I don't think it's an amazing idea to use interface types as map keys in the first place, because you have to deal with some caveats, the first is that:
The comparison operators == and != must be fully defined for operands of the key type
And now you need to be careful about the types that implement the interface. In theory, nobody stops a client from implementing your interface on a defined type with underlying unhashable type, e.g. type UncomparableSignature []int
So you would probably have to add an unexported method on your interface, so that client code outside that package can't implement it. But still, nothing stops code within the same package from implementing it, so this is, at best, maintenance overhead.
Then if the interface holds pointers to zero-values, it's even dependant on the implementation of the specs:
Pointers to distinct zero-size variables may or may not be equal.
Furthermore, you open yourself up to pesky bugs, like variables of type Signature that holds a nil will overwrite each other's values:
var foo Signature
var bar Signature
myMap[foo] = &Packet{/*pretending to have value 1*/}
myMap[bar] = &Packet{/*pretending to have value 2*/}
fmt.Println(myMap[foo]) // 2
A possible solution is, you could replace the map key with a unique id, and you enforce implementors to provide it by declaring the appropriate method on the interface Signature (this still assumes that the implementors can be coordinated to provide unique ids across all of them):
type Signature interface {
UniqueIdent() uint64 // or string, if you prefer
// ...other methods
}
and then
packet := myMap[someSignature.UniqueIdent()]

Reflect struct with struct methods

I'm playing around with reflect and I'm trying to reflect a struct, create a new one and try to call it.
The variables are working fine but when I reflect a new struct, the struct methods are not copied?
I created a simple example on the playground. On line 34 I receive that 0 Methods exist, but there should be 1 (SetName). Am I doing something wrong? already google for it since hours but do not get any solutions.
https://play.golang.org/p/yArjVLtWEaG
Thanks in advance
cheers pat
SetName is not a method of type company but of type *company. Sou you must create a pointer to company.

Get all structs that implements an interface in golang [duplicate]

I am a beginner in Go. I maybe thinking too traditional coming from years in other languages, but here is what I want to do in Go. Assume the following use case
I have interface I. This interface has functions, start() and stop()
There are many structs implementing the interface. struct A, struct B, struct C
When the application starts, I want to call start() on structs A, B and C
Similarly, when the application terminates, I want to call stop() on the A, B, C structs.
I do not want to hard code struct A, B and C anywhere in the code to call the start/stop functions. This is so that when I add struct D later (also implements interface I), the code will automatically work without modification.
In order to achieve this, I need to be able to say "Hey Go, give me all the types that implement interface I".
If I get back a slice of A, B and C, I can simply loop through and call the right methods at the right time.
Doable in Go?
The short answer is: No, that is not doable
Go is a strictly typed language. This allows the linker to leave out type definitions, methods and functions not used by the application.
That means, unless a type (such as struct A) are referenced and used somewhere, it will be omitted.
But in your comment, you mentioned you don't want the types but rather the currently existing instances of any type that implements the interface.
This is not possible either.
Alternative
My suggestion is to create a global map (or slice):
var instMap = map[string]StartStopper
And have each struct add an instance to that map with an init function that will automatically be called at the start of the application:
type A struct {}
func init() {
instMap["A"] = new(A)
}
Then when you want to start all the instances, just iterate over the map and call Start()
Edit
And if it is not a one-instance-per-type situation but rather multiple instances for each type, then you will have to add to the map (or slice) whenever a new instance is created. And you would have to remember deleting the instance from the map when it is not to be used anymore, or else it won't be handled by the Garbage Collector.

Resources