How to see resource values in the CLI?

Continuing the discussion from Does anybody know how to generate an API/ABI like sodildity?:

Is using events the way to see values in the Libra CLI client?

I want to see the values of a published resource. The resource’s module returns these values, but I’m not sure how the transaction script should relay them to the CLI, where I’m executing the script. Transaction scripts don’t return anything.

I want to see the values of a published resource.

Is that a resource in a module that you published or it’s like a LibraAccount.T? If you are asking about how one can read a resource stored in StateStore, the quick answer is we don’t have a good tool for doing that generically right now. The way how it works is as following:

Take LibraAccount.T as an example, we get the the resource by:

  1. Get account blob for the address where the resource is stored. This blob will look like a btreemap that maps a Vec(the path part in AccessPath) to Vec(the serialized resource).
  2. Construct the accesspath for the resource that you are interested in, and fetch the serialized resource in that btreemap. (see https://github.com/libra/libra/blob/master/types/src/account_config.rs#L116)
  3. Define a struct that matches with the move definition of your struct and deserialize the value with lcs. (see https://github.com/libra/libra/blob/master/types/src/account_config.rs#L80)

You can see implementation of this logic in https://github.com/libra/libra/blob/master/client/src/client_proxy.rs#L822

Perhaps you could offer advice for my use case that may also help others? This is a resource in a module I published. I’m making a simple escrow smart contract, where the seller must be confident that enough money is held for them in escrow before sending their item to the buyer. At the moment, the buyer calls a procedure that wraps up their LibraCoin.T with the seller’s address, and publishes that resource to their account (just like EarmarkedCoin in the docs). One way or another, the seller must then find out the coin value and address in that resource. At the moment, the seller calls a procedure that emits an event that contains that information, because that’s the only way I could think of to see that information in the CLI. But using events like that feels like a hack, and I was wondering if there was a better way. The only alternative I’ve thought of would be for the buyer’s procedure to emit an event, which is still using events, but I don’t know that the seller would be able to read that event.

Events are indeed the recommended way to implement this sort of pattern. Anytime you want to notify someone in the external world of something that happened on-chain, an event is almost always the answer.

For the escrow use-case you have in mind, I would imagine something like the following:

  • The seller publishes a module ForSale declaring a resource encoding what’s for sale, the price, etc, then publishes an instance of this resource under their account
  • A buyer declares their intention to purchase by calling a procedure like ForSale.buy(c: LibraCoin.T), which checks that c matches the stated price, locks c in escrow, and emits an event for the seller
1 Like

Yes, using an event to notify the seller when the buyer deposits money makes a lot of sense. Thanks.

How to subscribe new events for a given address in libra?

1 Like

Thanks Sam this is really helpful. Is there a resource that has pretty simple examples like this?