amgando
amgando

Reputation: 1591

do all NEAR blockchain transactions require a receiver account?

reading through some documentation here and saw that part of the definition of a transaction is that all actions are performed "on top of the receiver's account" and also that the receiver account is "the account towards which the transaction will be routed."

also in the nearlib SDK, the transactions interface includes a method called signTransaction that requires receiverId as a parameter

async function signTransaction(receiverId: string, nonce: number, actions: Action[], blockHash: Uint8Array, signer: Signer, accountId?: string, networkId?: string): Promise<[Uint8Array, SignedTransaction]> {

but looking over the list of transactions supported by nearcore I wonder why do some of these transaction require a receiver.

why would any transactions require a "receiver" except for maybe Transfer, AddKey, DeleteKey, and DeleteAccount?

amd I think of the idea of "receiver" too literally, as in "they receive the outcome or impact of the transaction"? and instead it's not the right way to think about it?

or is receiverId optional in some cases but the interface just requires a value to avoid validation cruft?

here's what I believe to be the full list of supported transactions

pub enum Action {
    CreateAccount(CreateAccountAction),
    DeployContract(DeployContractAction),
    FunctionCall(FunctionCallAction),
    Transfer(TransferAction),
    Stake(StakeAction),
    AddKey(AddKeyAction),
    DeleteKey(DeleteKeyAction),
    DeleteAccount(DeleteAccountAction),
}

Upvotes: 3

Views: 180

Answers (2)

Maksym Zavershynskyi
Maksym Zavershynskyi

Reputation: 876

Unfortunately, we don't have a good name to denote what we call "receiver". In some places in our code, we also call it "actor", because it actually refers to an account on which the action is performed opposed to an account which issued the action to perform (a.k.a "sender").

DeployContract, Stake, AddKey, DeleteKey require receiver==sender, in other words only an account itself can add/delete keys, stake and deploy a contract on itself, no other account can do it for it.

DeleteAccount is the same, it requires receiver==sender with one exception: If account is about to run out of balance due to storage rent and is below certain system-defined treshold any other account can delete it and claim the remaining balance.

CreateAccount, FunctionCall, and Transfer do not require receiver==sender. In case of the CreateAccount receiver should not exist at the moment of execution and will actually be created.

See the code that implements this logic: https://github.com/nearprotocol/nearcore/blob/ed43018851f8ec44f0a26b49fc9a863b71a1428f/runtime/runtime/src/actions.rs#L360

Upvotes: 2

berryguy
berryguy

Reputation: 1154

Conceptually every transaction always has a sender and a receiver, even though sometimes they might be the same. Because we always convert a transaction to a receipt that is sent to the receiver, it doesn't matter conceptually whether they are the same, even though in implementation there might be a difference.

Upvotes: 3

Related Questions