1"use strict";(self.webpackChunkopentezos=self.webpackChunkopentezos||[]).push([[4502],{15680:(e,t,a)=>{a.d(t,{xA:()=>c,yg:()=>g});var n=a(96540);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){o(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function i(e,t){if(null==e)return{};var a,n,o=function(e,t){if(null==e)return{};var a,n,o={},r=Object.keys(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var p=n.createContext({}),l=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,r=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),m=l(a),d=o,g=m["".concat(p,".").concat(d)]||m[d]||h[d]||r;return a?n.createElement(g,s(s({ref:t},c),{},{components:a})):n.createElement(g,s({ref:t},c))}));function g(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=a.length,s=new Array(r);s[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[m]="string"==typeof e?e:o,s[1]=i;for(var l=2;l<r;l++)s[l]=a[l];return n.createElement.apply(null,s)}return n.createElement.apply(null,a)}d.displayName="MDXCreateElement"},71905:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var n=a(58168),o=(a(96540),a(15680));const r={id:"operations",title:"Operations",authors:"Thomas Zoughebi, Aymeric Bethencourt, and Maxime Fernandez"},s=void 0,i={unversionedId:"tezos-basics/operations/operations",id:"tezos-basics/operations/operations",title:"Operations",description:"This chapter introduces the notion of Operations on Tezos. These are more commonly known as Transactions on other blockchains and in Tezos are a subset of operations. On Tezos, transactions are transfers of tokens and smart contracts calls. A few examples of operations that are not transactions on Tezos: Originations; attestations; proposals; ballots...",source:"@site/prebuild/tezos-basics/operations/operations.md",sourceDirName:"tezos-basics/operations",slug:"/tezos-basics/operations/",permalink:"/tezos-basics/operations/",draft:!1,editUrl:"https://gitlab.com/tezos-paris-hub/opentezos/-/blob/main/prebuild/tezos-basics/operations/operations.md",tags:[],version:"current",frontMatter:{id:"operations",title:"Operations",authors:"Thomas Zoughebi, Aymeric Bethencourt, and Maxime Fernandez"},sidebar:"docs",previous:{title:"Liquid Proof-of-Stake",permalink:"/tezos-basics/liquid-proof-of-stake/"},next:{title:"CLI and RPC",permalink:"/tezos-basics/cli-and-rpc/"}},p={},l=[{value:"Implicit accounts and originated accounts",id:"implicit-accounts-and-originated-accounts",level:2},{value:"Tezos operations",id:"tezos-operations",level:2},{value:"Operation Flow",id:"operation-flow",level:2},{value:"Pre-validator",id:"pre-validator",level:3},{value:"Mempool",id:"mempool",level:3},{value:"Baking and attestation",id:"baking-and-attestation",level:3},{value:"Validator",id:"validator",level:3},{value:"What have we learned so far?",id:"what-have-we-learned-so-far",level:2},{value:"References",id:"references",level:2}],c={toc:l},m="wrapper";
1function h(e){let{components:t,...r}=e;return(0,o.yg)(m,(0,n.A)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.yg)("p",null,"This chapter introduces the notion of ",(0,o.yg)("em",{parentName:"p"},"Operations")," on Tezos. These are more commonly known as ",(0,o.yg)("em",{parentName:"p"},"Transactions")," on other blockchains and in Tezos are a ",(0,o.yg)("strong",{parentName:"p"},"subset")," of operations. On Tezos, ",(0,o.yg)("em",{parentName:"p"},"transactions")," are transfers of tokens and smart contracts calls. A few examples of operations that are ",(0,o.yg)("strong",{parentName:"p"},"not")," transactions on Tezos: ",(0,o.yg)("em",{parentName:"p"},"Originations; attestations; proposals; ballots...")),(0,o.yg)("h2",{id:"implicit-accounts-and-originated-accounts"},"Implicit accounts and originated accounts"),(0,o.yg)("p",null,"Let's start by talking about the two types of addresses in Tezos ",(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/operations#references"},"[1]"),":"),(0,o.yg)("ul",null,(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("p",{parentName:"li"},"An ",(0,o.yg)("strong",{parentName:"p"},"implicit account")," is linked to a ",(0,o.yg)("strong",{parentName:"p"},"manager")," (see ",(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/smart-contracts#general-definition-of-a-tezos-smart-contract"},(0,o.yg)("em",{parentName:"a"},"General definition of a tezos smart contract")),"), which owns the ",(0,o.yg)("em",{parentName:"p"},"public key"),". The hash of the ",(0,o.yg)("em",{parentName:"p"},"public key")," outputs an ",(0,o.yg)("strong",{parentName:"p"},"address"),". Depending on the chosen ",(0,o.yg)("strong",{parentName:"p"},"D"),"igital ",(0,o.yg)("strong",{parentName:"p"},"S"),"ignature ",(0,o.yg)("strong",{parentName:"p"},"A"),"lgorithm's ",(0,o.yg)("strong",{parentName:"p"},"e"),"lliptic ",(0,o.yg)("strong",{parentName:"p"},"c"),"urve (see ",(0,o.yg)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm"},"ECDSA"),'), the latter starts with "',(0,o.yg)("strong",{parentName:"p"},(0,o.yg)("em",{parentName:"strong"},"tz1")),'" (Ed25519 curve), "',(0,o.yg)("strong",{parentName:"p"},(0,o.yg)("em",{parentName:"strong"},"tz2")),'" (',(0,o.yg)("a",{parentName:"p",href:"https://en.bitcoin.it/wiki/Secp256k1"},"Secp256k1"),' curve), "',(0,o.yg)("strong",{parentName:"p"},(0,o.yg)("em",{parentName:"strong"},"tz3")),'" (P256 curve) ',(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/operations#references"},"[2]"),' or "',(0,o.yg)("strong",{parentName:"p"},(0,o.yg)("em",{parentName:"strong"},"tz4")),'" (BLS curve).',(0,o.yg)("br",{parentName:"p"}),"\n","A ",(0,o.yg)("em",{parentName:"p"},"transfer")," operation to the account's address creates the account itself.",(0,o.yg)("br",{parentName:"p"}),"\n","Only ",(0,o.yg)("em",{parentName:"p"},"implicit")," accounts can be registered as ",(0,o.yg)("em",{parentName:"p"},"delegates")," and participate in the ",(0,o.yg)("em",{parentName:"p"},"baking process"),".")),(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("p",{parentName:"li"},(0,o.yg)("strong",{parentName:"p"},"Smart contracts"),' are also called "',(0,o.yg)("strong",{parentName:"p"},"originated accounts"),'" and are created with an ',(0,o.yg)("strong",{parentName:"p"},"origination")," operation (see the ",(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/smart-contracts#deployment-of-a-tezos-smart-contract"},(0,o.yg)("em",{parentName:"a"},"Smart Contracts"))," chapter). They don't have a private key and public key pair. Originated accounts' addresses start with ",(0,o.yg)("strong",{parentName:"p"},(0,o.yg)("em",{parentName:"strong"},"KT1")),".",(0,o.yg)("br",{parentName:"p"}),"\n","They run their Michelson code each time they receive a transaction."))),(0,o.yg)("h2",{id:"tezos-operations"},"Tezos operations"),(0,o.yg)("p",null,"An operation is usually a ",(0,o.yg)("em",{parentName:"p"},"message")," sent from one address to another."),(0,o.yg)("p",null,"Message representation:"),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-js"},"type operation = {\n amount: amount; // amount being sent\n parameters: data list;
1 // parameters passed to the script\n counter: int; // invoice id to avoid replay attacks\n destination: contract hash;\n}\n")),(0,o.yg)("p",null,"Example of an entrypoint call:"),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "branch": "BMXRpSqjJ9HnEeaSXj3YzM9jqB4kqDZemtJBGGqn5Sa9MepV1k7",\n "contents": [\n {\n "kind": "transaction",\n "source": "tz1YWK1gDPQx9N1Jh4JnmVre7xN6xhGGM4uC",\n "fee": "6678",\n "counter": "942780",\n "gas_limit": "63669",\n "storage_limit": "75",\n "amount": "0",\n "destination": "KT1S5hgipNSTFehZo7v81gq6fcLChbRwptqy",\n "parameters": {\n "entrypoint": "sellLand",\n "value": {\n "prim": "Pair",\n "args": [\n {"int": "100000000"},\n {"int": "11"}\n ]\n }\n }\n }\n ]\n}\n')),(0,o.yg)("p",null,"Example of a transaction between two ",(0,o.yg)("strong",{parentName:"p"},"implicit")," accounts:"),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "branch": "BKkwBsr6hfvj2MfaEydByALrASfCPzFBFSCs3iY7XaBLKRtwWj7",\n "contents": [\n {\n "kind": "transaction",\n "source": "tz1VAugX5LBcF4Anq1gEFr12LmsjqsCgsnPs",\n "fee": "444",\n "counter": "855452",\n "gas_limit": "1527",\n "storage_limit": "0",\n "amount": "100000000",\n "destination": "tz1YWK1gDPQx9N1Jh4JnmVre7xN6xhGGM4uC"\n }\n ]\n}\n')),(0,o.yg)("p",null,"Such an operation can be sent from an implicit account (if signed using the manager's private key) or programmatically by contract code execution. When the operation is received, and if the destination's contract code execution is valid, the amount is added to the destination's contract balance. This code can make use of the arguments passed on to it. It can read and write the contract's storage or post operations to other contracts."),(0,o.yg)("p",null,"As the example shows, there is also a ",(0,o.yg)("em",{parentName:"p"},"counter")," field, whose purpose is to prevent ",(0,o.yg)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Replay_attack"},"replay attacks"),". An operation is only valid if the contract's ",(0,o.yg)("em",{parentName:"p"},"counter")," is equal to the operation's ",(0,o.yg)("em",{parentName:"p"},"counter"),". Once an operation is applied, the ",(0,o.yg)("em",{parentName:"p"},"counter")," increases by one, preventing the operation from being reused."),(0,o.yg)("p",null,'The operation also includes the block hash ("',(0,o.yg)("em",{parentName:"p"},"branch"),'" field) of a recent block that the client considers valid. If an attacker ever succeeds in forcing a long reorganization with a fork, he will be unable to include this operation, thereby making the attack detectable.'),(0,o.yg)("p",null,'This last line of defense is named "',(0,o.yg)("em",{parentName:"p"},"TAPOS"),'": a statistical detection of a ',(0,o.yg)("em",{parentName:"p"},"Long Range Attack")," (see ",(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/liquid-proof-of-stake#long-range-attack"},(0,o.yg)("em",{parentName:"a"},"Liquid Proof of Stake"))," chapter) based on the fraction of moving coins. This kind of system prevents long reorganizations but is inefficient with short-term double-spending."),(0,o.yg)("p",null,"Currently the layer 1 of Tezos network on Seoul can process several hundred TPS (transactions per second) and has a deterministic time finality of 16 seconds (2 blocks). This speed may vary with future protocols. Finality is the time it takes for a block to be considered secure. As a comparison, ",(0,o.yg)("em",{parentName:"p"},"Bitcoin")," can process 7 TPS and has a probabilistic time finality of 60 minutes (6 valid blocks)."),(0,o.yg)("h2",{id:"operation-flow"},"Operation Flow"),(0,o.yg)("p",null,"The diagram below represents the life cycle of an operation:"),(0,o.yg)("p",null,(0,o.yg)("img",{alt:"1) Prevalidator (pre_filter, apply, post_filter) 2) Mempool 3) Baker 4) New block",src:a(36979).A,width:"1614",height:"326"})),(0,o.yg)("small",{className:"figure"},"FIGURE 1: Life cycle of an operation"),(0,o.yg)("p",null,'Nodes receive operations from clients via RPC or from a peer in the network. Note that this is how a typical Tezos node works on protocol "',(0,o.yg)("em",{parentName:"p"},"Alpha"),'".'),(0,o.yg)("h3",{id:"pre-validator"},"Pre-validator"),(0,o.yg)("p",null,"The ",(0,o.yg)("em",{parentName:"p"},"Pre-validator"),(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/operations#references"},"[4]")," is an operation's validation subsystem. It decides which operation to add to the ",(0,o.yg)("em",{parentName:"p"},"mempool")," (memory pool)."),(0,o.yg)("p",null,"The pre-validation consists in 3 steps:"),(0,o.yg)("ol",null,(0,o.yg)("li",{parentName:"ol"},(0,o.yg)("p",{parentName:"li"},"The ",(0,o.yg)("strong",{parentName:"p"},"Pre_filter")," step",(0,o.yg)("br",{parentName:"p"}),"\n","Checks that there is enough provided ",(0,o.yg)("em",{parentName:"p"},"gas")," (and if the sender's account has enough funds to pay)")),(0,o.yg)("li",{parentName:"ol"},(0,o.yg)("p",{parentName:"li"},"The ",(0,o.yg)("strong",{parentName:"p"},"Apply")," step",(0,o.yg)("br",{parentName:"p"}),"\n","Checks whether the operation is in adequacy with the current state of the Tezos chain")),(0,o.yg)("li",{parentName:"ol"},(0,o.yg)("p",{parentName:"li"},"The ",(0,o.yg)("strong",{parentName:"p"},"Post_filter")," step",(0,o.yg)("br",{parentName:"p"}),"\n","Decides whether to add the operation to the ",(0,o.yg)("em",{parentName:"p"},"mempool"),". If yes, it broadcasts the result"))),(0,o.yg)("p",null,"If ",(0,o.yg)("em",{parentName:"p"},"any")," of these steps triggers an error, the pre-validator doesn't add the operation to the mempool."),(0,o.yg)("h3",{id:"mempool"},"Mempool"),(0,o.yg)("p",null,'The node maintains a memory pool to keep track of "',(0,o.yg)("em",{parentName:"p"},(0,o.yg)("inlineCode",{parentName:"em"},"not-invalid-for-sure")),'" operations.'),(0,o.yg)("p",null,"There are two different kinds:"),(0,o.yg)("ul",null,(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("p",{parentName:"li"},(0,o.yg)("inlineCode",{parentName:"p"},"Known_valid"),": A list of valid operations ready to go in a block")),(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("p",{parentName:"li"},(0,o.yg)("inlineCode",{parentName:"p"},"Pending"),": A bounded set of operations eligible to broadcast. This set contains two sub-kinds of operations:"),(0,o.yg)("ul",{parentName:"li"},(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("p",{parentName:"li"},(0,o.yg)("inlineCode",{parentName:"p"},"branch_refused"),": an operation that could be valid in a different branch.")),(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("p",{parentName:"li"},(0,o.yg)("inlineCode",{parentName:"p"}
1,"branch_delayed"),": an operation that has come too soon (i.e. there's a gap in the account's counter)"))))),(0,o.yg)("p",null,"Operations in the mempool are broadcast to peers whenever the mempool is updated. A node fetches an operation from another remote peer's advertisement using the operation's hash."),(0,o.yg)("p",null,"A valid operation lives in the mempool until its addition to a valid block on a chain the node considers canonical (correct chain for the common history). If an operation isn't added to a block during its \"",(0,o.yg)("em",{parentName:"p"},(0,o.yg)("inlineCode",{parentName:"em"},"time-to-live")),"\" duration, it is removed from the mempool. As long as a transaction is in the mempool, the sender's address cannot normally issue another. However, it is possible to send multiple transactions at the same time in a batch."),(0,o.yg)("h3",{id:"baking-and-attestation"},"Baking and attestation"),(0,o.yg)("p",null,"The selected baker is free to select operations from the mempool, but he usually uses a ",(0,o.yg)("a",{parentName:"p",href:"https://octez.tezos.com/docs/protocols/004_Pt24m4xi.html#gas-and-fees"},"minimum fee")," filter. After a block creation, selected bakers attest the block. At the next block slot, the block producer collects the attestations from the previous level and adds them to the block."),(0,o.yg)("h3",{id:"validator"},"Validator"),(0,o.yg)("p",null,"The selected baker then shares the created block with the network. Once received, each node starts the block validation by calling the ",(0,o.yg)("em",{parentName:"p"},"Apply_block")," function. This function validates the block header by using the protocol parameters and verifies all the operations."),(0,o.yg)("p",null,"The block validation checks for errors such as too many operations, oversized operations, incorrect protocol versions, unauthorized validation passes, invalid fitness, unavailable protocols, errors while applying a transaction, and more ",(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/operations#references"},"[5]"),"."),(0,o.yg)("p",null,'Once a block is validated and is a candidate for the new head of the chain, it arrives to the "',(0,o.yg)("em",{parentName:"p"},"chain validator"),'" which checks if the fitness score',(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/operations#references"},"[6]")," of the new head is higher than the fitness score of the current one. If it is not, the block is ignored. If it is, then this block replaces the current head of the chain. The ",(0,o.yg)("em",{parentName:"p"},"chain validator")," then calls the ",(0,o.yg)("em",{parentName:"p"},"pre-validator")," to flush the ",(0,o.yg)("em",{parentName:"p"},"mempool"),". Finally, the new head is advertised to the peers using the ",(0,o.yg)("em",{parentName:"p"},"distributed_db's Advertise module"),(0,o.yg)("a",{parentName:"p",href:"/tezos-basics/operations#references"},"[7]"),". Of course, this block only becomes part of the canonical chain if future bakers decide to bake on top of it."),(0,o.yg)("h2",{id:"what-have-we-learned-so-far"},"What have we learned so far?"),(0,o.yg)("p",null,"In this chapter, we discovered the Tezos operations and how they are validated."),(0,o.yg)("p",null,'In the next "',(0,o.yg)("em",{parentName:"p"},"CLI and RPC"),'" chapter, we will learn how to issue them with a node.'),(0,o.yg)("h2",{id:"references"},"References"),(0,o.yg)("p",null,"[1]"," ",(0,o.yg)("a",{parentName:"p",href:"https://octez.tezos.com/docs/introduction/howtouse.html#user-accounts-and-smart-contracts"},"https://octez.tezos.com/docs/introduction/howtouse.html#user-accounts-and-smart-contracts")),(0,o.yg)("p",null,"[2]"," ",(0,o.yg)("a",{parentName:"p",href:"https://www.ocamlpro.com/2018/11/21/an-introduction-to-tezos-rpcs-signing-operations/"},"https://www.ocamlpro.com/2018/11/21/an-introduction-to-tezos-rpcs-signing-operations/")),(0,o.yg)("p",null,"[4]"," ",(0,o.yg)("a",{parentName:"p",href:"https://medium.com/tqtezos/lifecycle-of-an-operation-in-tezos-248c51038ec2"},"https://medium.com/tqtezos/lifecycle-of-an-operation-in-tezos-248c51038ec2")),(0,o.yg)("p",null,"[5]"," ",(0,o.yg)("a",{parentName:"p",href:"https://gitlab.com/tezos/tezos/blob/mainnet/src/lib_shell_services/block_validator_errors.ml"},"https://gitlab.com/tezos/tezos/blob/mainnet/src/lib_shell_services/block_validator_errors.ml")),(0,o.yg)("p",null,"[6]"," ",(0,o.yg)("a",{parentName:"p",href:"https://octez.tezos.com/docs/alpha/glossary.html#tezos"},"https://octez.tezos.com/docs/alpha/glossary.html#tezos")),(0,o.yg)("p",null,"[7]"," ",(0,o.yg)("a",{parentName:"p",href:"https://octez.tezos.com/docs/shell/validation.html#distributed-db"},"https://octez.tezos.com/docs/shell/validation.html#distributed-db")))}h.isMDXComponent=!0},36979:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/operation_flow-b7a7f914aaf7c9f3e0306aa7e8863378.svg"}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.