xdapp-book/technical/evm/bestPractices.html

427 lines
64 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js ayu">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Best Practices - Wormhole Development Book</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../../favicon.svg">
<link rel="shortcut icon" href="../../favicon.png">
<link rel="stylesheet" href="../../css/variables.css">
<link rel="stylesheet" href="../../css/general.css">
<link rel="stylesheet" href="../../css/chrome.css">
<link rel="stylesheet" href="../../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../../highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "ayu";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('ayu')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch (e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<a href="/" class="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 110" preserveAspectRatio="xMidYMid meet">
<defs>
<clipPath id="__lottie_element_594">
<rect width="600" height="110" x="0" y="0"></rect>
</clipPath>
<mask id="__lottie_element_596">
<path fill="#ffffff" clip-rule="nonzero"
d="M0,0 h600 v110 h-600 v-110 M0.1770000010728836,-0.014000000432133675 C0.1770000010728836,-0.014000000432133675 0,-0.014000000432133675 0,-0.014000000432133675 C0,-0.014000000432133675 0,0.9950000047683716 0,0.9950000047683716 C0,0.9950000047683716 0.1770000010728836,0.9950000047683716 0.1770000010728836,0.9950000047683716 C0.1770000010728836,0.9950000047683716 0.1770000010728836,-0.014000000432133675 0.1770000010728836,-0.014000000432133675"
fill-opacity="1"></path>
</mask>
<filter id="__lottie_element_597">
<feColorMatrix type="matrix" color-interpolation-filters="sRGB"
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"></feColorMatrix>
<feColorMatrix type="matrix" color-interpolation-filters="sRGB"
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"></feColorMatrix>
</filter>
<mask id="__lottie_element_599">
<path fill="#ffffff" clip-rule="nonzero"
d="M0,0 h600 v110 h-600 v-110 M0.1770000010728836,-0.014000000432133675 C0.1770000010728836,-0.014000000432133675 0,-0.014000000432133675 0,-0.014000000432133675 C0,-0.014000000432133675 0,0.9950000047683716 0,0.9950000047683716 C0,0.9950000047683716 0.1770000010728836,0.9950000047683716 0.1770000010728836,0.9950000047683716 C0.1770000010728836,0.9950000047683716 0.1770000010728836,-0.014000000432133675 0.1770000010728836,-0.014000000432133675"
fill-opacity="1"></path>
</mask>
<filter id="__lottie_element_600">
<feColorMatrix type="matrix" color-interpolation-filters="sRGB"
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"></feColorMatrix>
<feColorMatrix type="matrix" color-interpolation-filters="sRGB"
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"></feColorMatrix>
</filter>
</defs>
<g clip-path="url(#__lottie_element_594)">
<g mask="url(#__lottie_element_596)" filter="url(#__lottie_element_597)"
transform="matrix(1,0,0,1,6.5,3)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,51.62099838256836,51.57899856567383)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M0,51.57899856567383 C-13.680000305175781,51.56999969482422 -26.79800033569336,46.13399887084961 -36.47600173950195,36.46500015258789 C-46.15299987792969,26.79599952697754 -51.599998474121094,13.682999610900879 -51.62099838256836,0.003000000026077032 C-51.599998474121094,-13.678000450134277 -46.15299987792969,-26.79199981689453 -36.47600173950195,-36.46200180053711 C-26.798999786376953,-46.13100051879883 -13.680999755859375,-51.56800079345703 0,-51.57899856567383 C13.680999755859375,-51.56800079345703 26.798999786376953,-46.13100051879883 36.47600173950195,-36.46200180053711 C46.15399932861328,-26.79199981689453 51.599998474121094,-13.678000450134277 51.62099838256836,0.003000000026077032 C51.599998474121094,13.682999610900879 46.15299987792969,26.79599952697754 36.47600173950195,36.46500015258789 C26.79800033569336,46.13399887084961 13.680000305175781,51.56999969482422 0,51.57899856567383z M0,-47.608001708984375 C-12.628000259399414,-47.5989990234375 -24.73699951171875,-42.582000732421875 -33.66999816894531,-33.65599822998047 C-42.60300064086914,-24.729999542236328 -47.63100051879883,-12.625 -47.650001525878906,0.003000000026077032 C-47.63800048828125,12.631999969482422 -42.61199951171875,24.740999221801758 -33.676998138427734,33.66600036621094 C-24.743000030517578,42.59299850463867 -12.628999710083008,47.606998443603516 0,47.606998443603516 C12.630000114440918,47.606998443603516 24.743000030517578,42.59299850463867 33.678001403808594,33.66600036621094 C42.612998962402344,24.740999221801758 47.63800048828125,12.631999969482422 47.650001525878906,0.003000000026077032 C47.63100051879883,-12.625 42.604000091552734,-24.729999542236328 33.66999816894531,-33.65599822998047 C24.73699951171875,-42.582000732421875 12.628000259399414,-47.5989990234375 0,-47.608001708984375z">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,58.14699935913086,52.26499938964844)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M0.0010000000474974513,42.733001708984375 C-11.333000183105469,42.724998474121094 -22.20199966430664,38.22100067138672 -30.2189998626709,30.208999633789062 C-38.236000061035156,22.197999954223633 -42.74800109863281,11.333999633789062 -42.76599884033203,0 C-42.74800109863281,-11.333999633789062 -38.236000061035156,-22.197999954223633 -30.2189998626709,-30.209999084472656 C-22.20199966430664,-38.220001220703125 -11.333000183105469,-42.724998474121094 0.0010000000474974513,-42.733001708984375 C11.333999633789062,-42.724998474121094 22.201000213623047,-38.220001220703125 30.2189998626709,-30.209999084472656 C38.236000061035156,-22.197999954223633 42.749000549316406,-11.333999633789062 42.76599884033203,0 C42.749000549316406,11.333999633789062 38.236000061035156,22.197999954223633 30.2189998626709,30.208999633789062 C22.201000213623047,38.22100067138672 11.333999633789062,42.724998474121094 0.0010000000474974513,42.733001708984375z M0.0010000000474974513,-39.64899826049805 C-10.515000343322754,-39.63999938964844 -20.597999572753906,-35.46099853515625 -28.035999298095703,-28.027999877929688 C-35.4739990234375,-20.594999313354492 -39.65999984741211,-10.515000343322754 -39.67599868774414,0 C-39.65800094604492,10.515000343322754 -35.47100067138672,20.591999053955078 -28.034000396728516,28.023000717163086 C-20.59600067138672,35.45500183105469 -10.512999534606934,39.63399887084961 0.0010000000474974513,39.643001556396484 C10.515000343322754,39.63399887084961 20.59600067138672,35.45500183105469 28.034000396728516,28.023000717163086 C35.47200012207031,20.591999053955078 39.659000396728516,10.515000343322754 39.67599868774414,0 C39.659000396728516,-10.513999938964844 35.47200012207031,-20.591999053955078 28.034000396728516,-28.02400016784668 C20.59600067138672,-35.45600128173828 10.515000343322754,-39.63399887084961 0.0010000000474974513,-39.643001556396484 C0.0010000000474974513,-39.643001556396484 0.0010000000474974513,-39.64899826049805 0.0010000000474974513,-39.64899826049805z">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,64.6719970703125,52.957000732421875)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M0,33.8849983215332 C-8.987000465393066,33.87900161743164 -17.604000091552734,30.305999755859375 -23.961999893188477,23.95400047302246 C-30.319000244140625,17.60099983215332 -33.89699935913086,8.98799991607666 -33.9109992980957,0.0010000000474974513 C-33.89699935913086,-8.986000061035156 -30.319000244140625,-17.601999282836914 -23.961999893188477,-23.95400047302246 C-17.604000091552734,-30.305999755859375 -8.987000465393066,-33.87799835205078 0,-33.8849983215332 C8.98799991607666,-33.880001068115234 17.606000900268555,-30.30900001525879 23.96299934387207,-23.95599937438965 C30.320999145507812,-17.60300064086914 33.89899826049805,-8.987000465393066 33.9109992980957,0.0010000000474974513 C33.89699935913086,8.98799991607666 30.319000244140625,17.60099983215332 23.961000442504883,23.95400047302246 C17.604000091552734,30.305999755859375 8.987000465393066,33.87900161743164 0,33.8849983215332z M0,-31.680999755859375 C-8.402999877929688,-31.676000595092773 -16.461000442504883,-28.336999893188477 -22.405000686645508,-22.398000717163086 C-28.350000381469727,-16.45800018310547 -31.69499969482422,-8.402999877929688 -31.70800018310547,0 C-31.69300079345703,8.402000427246094 -28.347000122070312,16.45599937438965 -22.402999877929688,22.393999099731445 C-16.458999633789062,28.332000732421875 -8.402000427246094,31.66900062561035 0,31.673999786376953 C8.402000427246094,31.66900062561035 16.458999633789062,28.332000732421875 22.402999877929688,22.393999099731445 C28.347000122070312,16.45599937438965 31.69300079345703,8.402000427246094 31.70800018310547,0 C31.69499969482422,-8.402999877929688 28.350000381469727,-16.45800018310547 22.405000686645508,-22.398000717163086 C16.461000442504883,-28.336999893188477 8.402999877929688,-31.676000595092773 0,-31.680999755859375z">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,71.1969985961914,53.64400100708008)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M0,25.040000915527344 C-6.639999866485596,25.03499984741211 -13.006999969482422,22.393999099731445 -17.704999923706055,17.701000213623047 C-22.402000427246094,13.008000373840332 -25.045000076293945,6.642000198364258 -25.055999755859375,0.003000000026077032 C-25.047000885009766,-6.638999938964844 -22.40399932861328,-13.005000114440918 -17.707000732421875,-17.698999404907227 C-13.008999824523926,-22.395000457763672 -6.640999794006348,-25.03499984741211 0,-25.040000915527344 C6.642000198364258,-25.03499984741211 13.010000228881836,-22.395000457763672 17.707000732421875,-17.698999404907227 C22.405000686645508,-13.005000114440918 25.047000885009766,-6.638999938964844 25.055999755859375,0.003000000026077032 C25.04599952697754,6.642000198364258 22.402000427246094,13.008000373840332 17.704999923706055,17.701000213623047 C13.008000373840332,22.393999099731445 6.640999794006348,25.03499984741211 0,25.040000915527344z M0,-23.716999053955078 C-6.289999961853027,-23.711999893188477 -12.321000099182129,-21.209999084472656 -16.770999908447266,-16.763999938964844 C-21.219999313354492,-12.317000389099121 -23.724000930786133,-6.288000106811523 -23.73200035095215,0.003000000026077032 C-23.722000122070312,6.291999816894531 -21.216999053955078,12.321000099182129 -16.768999099731445,16.766000747680664 C-12.319000244140625,21.211999893188477 -6.289000034332275,23.709999084472656 0,23.715999603271484 C6.289999961853027,23.709999084472656 12.319999694824219,21.211999893188477 16.768999099731445,16.766000747680664 C21.218000411987305,12.321000099182129 23.722000122070312,6.291999816894531 23.73200035095215,0.003000000026077032 C23.724000930786133,-6.288000106811523 21.22100067138672,-12.317000389099121 16.770999908447266,-16.763999938964844 C12.321999549865723,-21.209999084472656 6.290999889373779,-23.711999893188477 0,-23.716999053955078z">
</path>
</g>
</g>
<g mask="url(#__lottie_element_599)" filter="url(#__lottie_element_600)"
transform="matrix(1,0,0,1,6.5,3)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,165.5959930419922,50.316001892089844)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M26.5310001373291,-18.825000762939453 C26.5310001373291,-18.825000762939453 12.987000465393066,19.18199920654297 12.987000465393066,19.18199920654297 C12.925000190734863,19.364999771118164 12.803000450134277,19.523000717163086 12.640000343322754,19.6299991607666 C12.47700023651123,19.73699951171875 12.282999992370605,19.785999298095703 12.08899974822998,19.770999908447266 C12.08899974822998,19.770999908447266 11.062000274658203,19.770999908447266 11.062000274658203,19.770999908447266 C10.866999626159668,19.77899932861328 10.673999786376953,19.72599983215332 10.510000228881836,19.6200008392334 C10.347000122070312,19.514999389648438 10.220000267028809,19.36199951171875 10.147000312805176,19.18199920654297 C10.147000312805176,19.18199920654297 -0.007000000216066837,-7.4730000495910645 -0.007000000216066837,-7.4730000495910645 C-0.007000000216066837,-7.4730000495910645 -10.144000053405762,19.18199920654297 -10.144000053405762,19.18199920654297 C-10.211000442504883,19.36199951171875 -10.335000038146973,19.516000747680664 -10.496000289916992,19.621999740600586 C-10.657999992370605,19.72800064086914 -10.848999977111816,19.780000686645508 -11.043000221252441,19.770999908447266 C-11.043000221252441,19.770999908447266 -12.086000442504883,19.770999908447266 -12.086000442504883,19.770999908447266 C-12.279000282287598,19.7810001373291 -12.470999717712402,19.729999542236328 -12.633000373840332,19.624000549316406 C-12.795000076293945,19.51799964904785 -12.918000221252441,19.363000869750977 -12.984000205993652,19.18199920654297 C-12.984000205993652,19.18199920654297 -26.527999877929688,-18.812000274658203 -26.527999877929688,-18.812000274658203 C-26.736000061035156,-19.400999069213867 -26.511999130249023,-19.766000747680664 -25.934999465942383,-19.766000747680664 C-25.934999465942383,-19.766000747680664 -21.743000030517578,-19.766000747680664 -21.743000030517578,-19.766000747680664 C-21.54599952697754,-19.78499984741211 -21.347999572753906,-19.73900032043457 -21.180999755859375,-19.631999969482422 C-21.014999389648438,-19.524999618530273 -20.889999389648438,-19.364999771118164 -20.827999114990234,-19.17799949645996 C-20.827999114990234,-19.17799949645996 -11.173999786376953,9.597999572753906 -11.173999786376953,9.597999572753906 C-11.173999786376953,9.597999572753906 -1.3580000400543213,-16.7549991607666 -1.3580000400543213,-16.7549991607666 C-1.2879999876022339,-16.937000274658203 -1.1610000133514404,-17.090999603271484 -0.996999979019165,-17.19700050354004 C-0.8320000171661377,-17.30299949645996 -0.6389999985694885,-17.354000091552734 -0.4429999887943268,-17.3439998626709 C-0.4429999887943268,-17.3439998626709 0.4390000104904175,-17.3439998626709 0.4390000104904175,-17.3439998626709 C0.6330000162124634,-17.354000091552734 0.8240000009536743,-17.301000595092773 0.9860000014305115,-17.19499969482422 C1.1480000019073486,-17.089000701904297 1.2710000276565552,-16.93600082397461 1.3380000591278076,-16.7549991607666 C1.3380000591278076,-16.7549991607666 11.444999694824219,9.597999572753906 11.444999694824219,9.597999572753906 C11.444999694824219,9.597999572753906 20.874000549316406,-19.17799949645996 20.874000549316406,-19.17799949645996 C20.937000274658203,-19.364999771118164 21.06100082397461,-19.524999618530273 21.22800064086914,-19.631999969482422 C21.393999099731445,-19.73900032043457 21.591999053955078,-19.78499984741211 21.790000915527344,-19.766000747680664 C21.790000915527344,-19.766000747680664 25.917999267578125,-19.766000747680664 25.917999267578125,-19.766000747680664 C26.51099967956543,-19.766000747680664 26.736000061035156,-19.400999069213867 26.527999877929688,-18.825000762939453">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,230.92799377441406,49.98500061035156)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M20.148000717163086,0.017999999225139618 C20.110000610351562,3.931999921798706 18.905000686645508,7.747000217437744 16.68600082397461,10.984000205993652 C14.467000007629395,14.220000267028809 11.333000183105469,16.732999801635742 7.677999973297119,18.20400047302246 C4.021999835968018,19.677000045776367 0.009999999776482582,20.042999267578125 -3.8540000915527344,19.256999969482422 C-7.7179999351501465,18.469999313354492 -11.26099967956543,16.566999435424805 -14.03600025177002,13.78600025177002 C-16.812000274658203,11.003999710083008 -18.69700050354004,7.46999979019165 -19.452999114990234,3.628000020980835 C-20.208999633789062,-0.21299999952316284 -19.80299949645996,-4.191999912261963 -18.28499984741211,-7.804999828338623 C-16.767000198364258,-11.418000221252441 -14.204999923706055,-14.505000114440918 -10.92300033569336,-16.676000595092773 C-7.639999866485596,-18.847000122070312 -3.7839999198913574,-20.0049991607666 0.16099999845027924,-20.0049991607666 C2.812000036239624,-20.04199981689453 5.443999767303467,-19.548999786376953 7.8979997634887695,-18.55299949645996 C10.352999687194824,-17.558000564575195 12.579000473022461,-16.08099937438965 14.444999694824219,-14.211999893188477 C16.31100082397461,-12.342000007629395 17.777999877929688,-10.119000434875488 18.757999420166016,-7.673999786376953 C19.73699951171875,-5.229000091552734 20.209999084472656,-2.611999988555908 20.148000717163086,0.017999999225139618z M14.604999542236328,0.017999999225139618 C14.604999542236328,-9.196000099182129 8.54800033569336,-15.543999671936035 0.16099999845027924,-15.543999671936035 C-8.22599983215332,-15.543999671936035 -14.281000137329102,-9.196000099182129 -14.281000137329102,0.017999999225139618 C-14.281000137329102,9.232999801635742 -8.22599983215332,15.579000473022461 0.16099999845027924,15.579000473022461 C8.54800033569336,15.579000473022461 14.604999542236328,9.232999801635742 14.604999542236328,0.017999999225139618z">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,289.0769958496094,50.01300048828125)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M14.923999786376953,17.861000061035156 C15.052000045776367,18.006999969482422 15.133000373840332,18.190000534057617 15.154000282287598,18.382999420166016 C15.175999641418457,18.576000213623047 15.137999534606934,18.770000457763672 15.045999526977539,18.94099998474121 C14.95300006866455,19.11199951171875 14.810999870300293,19.250999450683594 14.63700008392334,19.34000015258789 C14.46399974822998,19.429000854492188 14.267000198364258,19.46299934387207 14.072999954223633,19.43899917602539 C14.072999954223633,19.43899917602539 10.29699993133545,19.43899917602539 10.29699993133545,19.43899917602539 C10.173999786376953,19.434999465942383 10.055000305175781,19.402000427246094 9.947999954223633,19.34000015258789 C9.842000007629395,19.280000686645508 9.75100040435791,19.194000244140625 9.685999870300293,19.089000701904297 C9.685999870300293,19.089000701904297 0.20999999344348907,4.900000095367432 0.20999999344348907,4.900000095367432 C0.20999999344348907,4.900000095367432 -9.973999977111816,4.900000095367432 -9.973999977111816,4.900000095367432 C-9.973999977111816,4.900000095367432 -9.973999977111816,18.643999099731445 -9.973999977111816,18.643999099731445 C-9.97700023651123,18.854999542236328 -10.062000274658203,19.055999755859375 -10.211999893188477,19.20599937438965 C-10.362000465393066,19.354999542236328 -10.567000389099121,19.440000534057617 -10.779000282287598,19.44300079345703 C-10.779000282287598,19.44300079345703 -14.467000007629395,19.44300079345703 -14.467000007629395,19.44300079345703 C-14.678999900817871,19.43899917602539 -14.880999565124512,19.35300064086914 -15.031000137329102,19.20400047302246 C-15.180999755859375,19.054000854492188 -15.265999794006348,18.854000091552734 -15.267999649047852,18.643999099731445 C-15.267999649047852,18.643999099731445 -15.267999649047852,-18.663000106811523 -15.267999649047852,-18.663000106811523 C-15.265000343322754,-18.874000549316406 -15.180000305175781,-19.075000762939453 -15.031000137329102,-19.224000930786133 C-14.881999969482422,-19.37299919128418 -14.678999900817871,-19.458999633789062 -14.467000007629395,-19.46299934387207 C-14.467000007629395,-19.46299934387207 0.039000000804662704,-19.46299934387207 0.039000000804662704,-19.46299934387207 C10.192000389099121,-19.46299934387207 15.206000328063965,-14.168000221252441 15.206000328063965,-7.2829999923706055 C15.267999649047852,-4.546999931335449 14.340999603271484,-1.878999948501587 12.593999862670898,0.23800000548362732 C10.847000122070312,2.3550000190734863 8.395000457763672,3.7820000648498535 5.679999828338623,4.260000228881836 C5.679999828338623,4.260000228881836 14.923999786376953,17.861000061035156 14.923999786376953,17.861000061035156z M-0.9959999918937683,0.43799999356269836 C6.98799991607666,0.43799999356269836 9.668999671936035,-2.8480000495910645 9.668999671936035,-7.28000020980835 C9.668999671936035,-11.711999893188477 6.98799991607666,-14.996999740600586 -0.9959999918937683,-14.996999740600586 C-0.9959999918937683,-14.996999740600586 -9.977999687194824,-14.996999740600586 -9.977999687194824,-14.996999740600586 C-9.977999687194824,-14.996999740600586 -9.977999687194824,0.43799999356269836 -9.977999687194824,0.43799999356269836 C-9.977999687194824,0.43799999356269836 -0.9959999918937683,0.43799999356269836 -0.9959999918937683,0.43799999356269836z">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,347.6789855957031,49.689998626708984)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M18.70400047302246,-19.766000747680664 C18.70400047302246,-19.766000747680664 19.908000946044922,-19.766000747680664 19.908000946044922,-19.766000747680664 C20.016000747680664,-19.773000717163086 20.12299919128418,-19.756999969482422 20.225000381469727,-19.7189998626709 C20.325000762939453,-19.68199920654297 20.416000366210938,-19.62299919128418 20.493000030517578,-19.547000885009766 C20.569000244140625,-19.472000122070312 20.628000259399414,-19.381000518798828 20.666000366210938,-19.2810001373291 C20.70400047302246,-19.180999755859375 20.72100067138672,-19.073999404907227 20.71299934387207,-18.966999053955078 C20.71299934387207,-18.966999053955078 20.71299934387207,18.9689998626709 20.71299934387207,18.9689998626709 C20.72100067138672,19.075000762939453 20.70400047302246,19.183000564575195 20.666000366210938,19.283000946044922 C20.628000259399414,19.382999420166016 20.569000244140625,19.472999572753906 20.493000030517578,19.548999786376953 C20.416000366210938,19.624000549316406 20.325000762939453,19.683000564575195 20.225000381469727,19.72100067138672 C20.12299919128418,19.757999420166016 20.016000747680664,19.774999618530273 19.908000946044922,19.76799964904785 C19.908000946044922,19.76799964904785 16.22100067138672,19.76799964904785 16.22100067138672,19.76799964904785 C16.11199951171875,19.774999618530273 16.003999710083008,19.757999420166016 15.904000282287598,19.72100067138672 C15.803999900817871,19.683000564575195 15.711000442504883,19.624000549316406 15.63599967956543,19.548999786376953 C15.559000015258789,19.472999572753906 15.5,19.382999420166016 15.461999893188477,19.283000946044922 C15.423999786376953,19.183000564575195 15.407999992370605,19.075000762939453 15.414999961853027,18.9689998626709 C15.414999961853027,18.9689998626709 15.414999961853027,-7.9629998207092285 15.414999961853027,-7.9629998207092285 C15.414999961853027,-7.9629998207092285 0.5540000200271606,13.385000228881836 0.5540000200271606,13.385000228881836 C0.5040000081062317,13.489999771118164 0.4269999861717224,13.579000473022461 0.328000009059906,13.642999649047852 C0.2290000021457672,13.704999923706055 0.11500000208616257,13.73799991607666 -0.0020000000949949026,13.73799991607666 C-0.11900000274181366,13.73799991607666 -0.2329999953508377,13.704999923706055 -0.3319999873638153,13.642999649047852 C-0.4300000071525574,13.579000473022461 -0.5090000033378601,13.489999771118164 -0.5569999814033508,13.385000228881836 C-0.5569999814033508,13.385000228881836 -15.416000366210938,-7.9629998207092285 -15.416000366210938,-7.9629998207092285 C-15.416000366210938,-7.9629998207092285 -15.416000366210938,18.96500015258789 -15.416000366210938,18.96500015258789 C-15.409000396728516,19.07200050354004 -15.425000190734863,19.18000030517578 -15.463000297546387,19.27899932861328 C-15.50100040435791,19.3799991607666 -15.5600004196167,19.47100067138672 -15.63599967956543,19.54599952697754 C-15.711999893188477,19.621999740600586 -15.803999900817871,19.68000030517578 -15.904000282287598,19.716999053955078 C-16.0049991607666,19.7549991607666 -16.11199951171875,19.770999908447266 -16.22100067138672,19.763999938964844 C-16.22100067138672,19.763999938964844 -19.909000396728516,19.763999938964844 -19.909000396728516,19.763999938964844 C-20.017000198364258,19.770999908447266 -20.124000549316406,19.7549991607666 -20.225000381469727,19.716999053955078 C-20.326000213623047,19.68000030517578 -20.41699981689453,19.621999740600586 -20.493999481201172,19.54599952697754 C-20.569000244140625,19.47100067138672 -20.628999710083008,19.3799991607666 -20.66699981689453,19.27899932861328 C-20.704999923706055,19.18000030517578 -20.72100067138672,19.07200050354004 -20.714000701904297,18.96500015258789 C-20.714000701904297,18.96500015258789 -20.714000701904297,-18.97100067138672 -20.714000701904297,-18.97100067138672 C-20.72100067138672,-19.077999114990234 -20.704999923706055,-19.18400001525879 -20.66699981689453,-19.284000396728516 C-20.628999710083008,-19.384000778198242 -20.569000244140625,-19.475000381469727 -20.493999481201172,-19.551000595092773 C-20.41699981689453,-19.625999450683594 -20.326000213623047,-19.684999465942383 -20.225000381469727,-19.722999572753906 C-20.124000549316406,-19.760000228881836 -20.017000198364258,-19.775999069213867 -19.909000396728516,-19.768999099731445 C-19.909000396728516,-19.768999099731445 -18.7189998626709,-19.768999099731445 -18.7189998626709,-19.768999099731445 C-18.518999099731445,-19.76799964904785 -18.320999145507812,-19.7189998626709 -18.14699935913086,-19.624000549316406 C-17.97100067138672,-19.52899932861328 -17.820999145507812,-19.39299964904785 -17.71299934387207,-19.226999282836914 C-17.71299934387207,-19.226999282836914 -0.007000000216066837,5.309000015258789 -0.007000000216066837,5.309000015258789 C-0.007000000216066837,5.309000015258789 17.711999893188477,-19.226999282836914 17.711999893188477,-19.226999282836914 C17.815000534057617,-19.392000198364258 17.959999084472656,-19.527000427246094 18.131000518798828,-19.621999740600586 C18.30299949645996,-19.716999053955078 18.4950008392334,-19.76799964904785 18.69099998474121,-19.768999099731445">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,410.510986328125,50.000999450683594)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M17.5,-18.652000427246094 C17.5,-18.652000427246094 17.5,18.652000427246094 17.5,18.652000427246094 C17.496000289916992,18.863000869750977 17.40999984741211,19.06399917602539 17.260000228881836,19.214000701904297 C17.108999252319336,19.36199951171875 16.9060001373291,19.447999954223633 16.694000244140625,19.451000213623047 C16.694000244140625,19.451000213623047 13.005000114440918,19.451000213623047 13.005000114440918,19.451000213623047 C12.793000221252441,19.447999954223633 12.59000015258789,19.36199951171875 12.4399995803833,19.214000701904297 C12.289999961853027,19.06399917602539 12.204999923706055,18.863000869750977 12.20199966430664,18.652000427246094 C12.20199966430664,18.652000427246094 12.20199966430664,1.6579999923706055 12.20199966430664,1.6579999923706055 C12.20199966430664,1.6579999923706055 -12.201000213623047,1.6579999923706055 -12.201000213623047,1.6579999923706055 C-12.201000213623047,1.6579999923706055 -12.201000213623047,18.652000427246094 -12.201000213623047,18.652000427246094 C-12.204999923706055,18.863000869750977 -12.291000366210938,19.06399917602539 -12.4399995803833,19.214000701904297 C-12.590999603271484,19.36199951171875 -12.793000221252441,19.447999954223633 -13.005000114440918,19.451000213623047 C-13.005000114440918,19.451000213623047 -16.694000244140625,19.451000213623047 -16.694000244140625,19.451000213623047 C-16.9060001373291,19.447999954223633 -17.107999801635742,19.36199951171875 -17.259000778198242,19.214000701904297 C-17.409000396728516,19.06399917602539 -17.496000289916992,18.863000869750977 -17.5,18.652000427246094 C-17.5,18.652000427246094 -17.5,-18.652000427246094 -17.5,-18.652000427246094 C-17.496000289916992,-18.863000869750977 -17.409000396728516,-19.062999725341797 -17.259000778198242,-19.211999893188477 C-17.107999801635742,-19.361000061035156 -16.9060001373291,-19.44700050354004 -16.694000244140625,-19.451000213623047 C-16.694000244140625,-19.451000213623047 -13.005000114440918,-19.451000213623047 -13.005000114440918,-19.451000213623047 C-12.793000221252441,-19.44700050354004 -12.590999603271484,-19.361000061035156 -12.4399995803833,-19.211999893188477 C-12.291000366210938,-19.062999725341797 -12.204999923706055,-18.863000869750977 -12.201000213623047,-18.652000427246094 C-12.201000213623047,-18.652000427246094 -12.201000213623047,-2.805000066757202 -12.201000213623047,-2.805000066757202 C-12.201000213623047,-2.805000066757202 12.20199966430664,-2.805000066757202 12.20199966430664,-2.805000066757202 C12.20199966430664,-2.805000066757202 12.20199966430664,-18.652000427246094 12.20199966430664,-18.652000427246094 C12.204999923706055,-18.863000869750977 12.289999961853027,-19.062999725341797 12.4399995803833,-19.211999893188477 C12.59000015258789,-19.361000061035156 12.793000221252441,-19.44700050354004 13.005000114440918,-19.451000213623047 C13.005000114440918,-19.451000213623047 16.694000244140625,-19.451000213623047 16.694000244140625,-19.451000213623047 C16.9060001373291,-19.44700050354004 17.108999252319336,-19.361000061035156 17.260000228881836,-19.211999893188477 C17.40999984741211,-19.062999725341797 17.496000289916992,-18.863000869750977 17.5,-18.652000427246094z">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,470.5679931640625,49.98500061035156)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M20.14699935913086,0.017999999225139618 C20.108999252319336,3.931999921798706 18.905000686645508,7.747000217437744 16.68600082397461,10.984000205993652 C14.467000007629395,14.220000267028809 11.333000183105469,16.732999801635742 7.677999973297119,18.20400047302246 C4.0229997634887695,19.677000045776367 0.009999999776482582,20.042999267578125 -3.8540000915527344,19.256999969482422 C-7.7179999351501465,18.469999313354492 -11.26099967956543,16.566999435424805 -14.036999702453613,13.78600025177002 C-16.812999725341797,11.003999710083008 -18.697999954223633,7.46999979019165 -19.45400047302246,3.628000020980835 C-20.208999633789062,-0.21299999952316284 -19.80299949645996,-4.191999912261963 -18.28499984741211,-7.804999828338623 C-16.767000198364258,-11.418000221252441 -14.204999923706055,-14.505000114440918 -10.92300033569336,-16.676000595092773 C-7.639999866485596,-18.847000122070312 -3.7839999198913574,-20.0049991607666 0.16099999845027924,-20.0049991607666 C2.812000036239624,-20.04199981689453 5.442999839782715,-19.548999786376953 7.8979997634887695,-18.55299949645996 C10.35200023651123,-17.558000564575195 12.579000473022461,-16.08099937438965 14.444000244140625,-14.211999893188477 C16.309999465942383,-12.342000007629395 17.777000427246094,-10.119000434875488 18.756999969482422,-7.673999786376953 C19.73699951171875,-5.229000091552734 20.208999633789062,-2.611999988555908 20.14699935913086,0.017999999225139618z M14.604000091552734,0.017999999225139618 C14.604000091552734,-9.196000099182129 8.54800033569336,-15.543999671936035 0.16099999845027924,-15.543999671936035 C-8.22599983215332,-15.543999671936035 -14.281999588012695,-9.196000099182129 -14.281999588012695,0.017999999225139618 C-14.281999588012695,9.232999801635742 -8.22599983215332,15.579000473022461 0.16099999845027924,15.579000473022461 C8.54800033569336,15.579000473022461 14.604000091552734,9.232999801635742 14.604000091552734,0.017999999225139618z">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,527.3350219726562,50.00400161743164)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M13.864999771118164,15.779999732971191 C13.864999771118164,15.779999732971191 13.864999771118164,18.648000717163086 13.864999771118164,18.648000717163086 C13.871999740600586,18.756000518798828 13.854999542236328,18.86199951171875 13.817000389099121,18.961999893188477 C13.779000282287598,19.062000274658203 13.718999862670898,19.152999877929688 13.642999649047852,19.22800064086914 C13.567000389099121,19.304000854492188 13.475000381469727,19.363000869750977 13.375,19.399999618530273 C13.27400016784668,19.437999725341797 13.166999816894531,19.45400047302246 13.057999610900879,19.44700050354004 C13.057999610900879,19.44700050354004 -13.07699966430664,19.44700050354004 -13.07699966430664,19.44700050354004 C-13.288999557495117,19.444000244140625 -13.491999626159668,19.357999801635742 -13.642000198364258,19.209999084472656 C-13.791999816894531,19.059999465942383 -13.878000259399414,18.858999252319336 -13.881999969482422,18.648000717163086 C-13.881999969482422,18.648000717163086 -13.881999969482422,-18.655000686645508 -13.881999969482422,-18.655000686645508 C-13.878000259399414,-18.865999221801758 -13.791999816894531,-19.066999435424805 -13.642000198364258,-19.215999603271484 C-13.491999626159668,-19.364999771118164 -13.288999557495117,-19.450000762939453 -13.07699966430664,-19.45400047302246 C-13.07699966430664,-19.45400047302246 -9.387999534606934,-19.45400047302246 -9.387999534606934,-19.45400047302246 C-9.175999641418457,-19.448999404907227 -8.973999977111816,-19.36400032043457 -8.824999809265137,-19.21500015258789 C-8.675000190734863,-19.06599998474121 -8.59000015258789,-18.865999221801758 -8.586999893188477,-18.655000686645508 C-8.586999893188477,-18.655000686645508 -8.586999893188477,14.980999946594238 -8.586999893188477,14.980999946594238 C-8.586999893188477,14.980999946594238 13.069000244140625,14.980999946594238 13.069000244140625,14.980999946594238 C13.177000045776367,14.973999977111816 13.284000396728516,14.991000175476074 13.385000228881836,15.027999877929688 C13.486000061035156,15.065999984741211 13.57699966430664,15.125 13.654000282287598,15.199999809265137 C13.729999542236328,15.276000022888184 13.788999557495117,15.366999626159668 13.82699966430664,15.467000007629395 C13.864999771118164,15.565999984741211 13.880999565124512,15.673999786376953 13.87399959564209,15.779999732971191">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,577.2100219726562,49.99800109863281)">
<path fill="rgb(0,0,0)" fill-opacity="1"
d=" M14.913000106811523,15.784000396728516 C14.913000106811523,15.784000396728516 14.913000106811523,18.652000427246094 14.913000106811523,18.652000427246094 C14.920000076293945,18.759000778198242 14.902999877929688,18.864999771118164 14.864999771118164,18.96500015258789 C14.82699966430664,19.06399917602539 14.767999649047852,19.1560001373291 14.692999839782715,19.23200035095215 C14.616000175476074,19.30699920654297 14.524999618530273,19.365999221801758 14.423999786376953,19.40399932861328 C14.322999954223633,19.44099998474121 14.21500015258789,19.45800018310547 14.107000350952148,19.451000213623047 C14.107000350952148,19.451000213623047 -14.116999626159668,19.451000213623047 -14.116999626159668,19.451000213623047 C-14.329000473022461,19.44700050354004 -14.531999588012695,19.36199951171875 -14.682000160217285,19.21299934387207 C-14.831999778747559,19.06399917602539 -14.918000221252441,18.863000869750977 -14.92199993133545,18.652000427246094 C-14.92199993133545,18.652000427246094 -14.92199993133545,-18.652000427246094 -14.92199993133545,-18.652000427246094 C-14.918000221252441,-18.86199951171875 -14.831999778747559,-19.065000534057617 -14.682000160217285,-19.214000701904297 C-14.531999588012695,-19.363000869750977 -14.329000473022461,-19.447999954223633 -14.116999626159668,-19.451000213623047 C-14.116999626159668,-19.451000213623047 13.468000411987305,-19.451000213623047 13.468000411987305,-19.451000213623047 C13.574999809265137,-19.45800018310547 13.682999610900879,-19.44099998474121 13.784000396728516,-19.40399932861328 C13.885000228881836,-19.365999221801758 13.97599983215332,-19.30699920654297 14.052000045776367,-19.23200035095215 C14.128000259399414,-19.1560001373291 14.185999870300293,-19.065000534057617 14.223999977111816,-18.96500015258789 C14.26200008392334,-18.864999771118164 14.279999732971191,-18.757999420166016 14.27299976348877,-18.652000427246094 C14.27299976348877,-18.652000427246094 14.27299976348877,-15.782999992370605 14.27299976348877,-15.782999992370605 C14.279999732971191,-15.675999641418457 14.26200008392334,-15.569999694824219 14.223999977111816,-15.468999862670898 C14.185999870300293,-15.369999885559082 14.128000259399414,-15.279000282287598 14.052000045776367,-15.20300006866455 C13.97599983215332,-15.128000259399414 13.885000228881836,-15.069000244140625 13.784000396728516,-15.031000137329102 C13.682999610900879,-14.994000434875488 13.574999809265137,-14.977999687194824 13.468000411987305,-14.984999656677246 C13.468000411987305,-14.984999656677246 -9.633000373840332,-14.984999656677246 -9.633000373840332,-14.984999656677246 C-9.633000373840332,-14.984999656677246 -9.633000373840332,-2.805000066757202 -9.633000373840332,-2.805000066757202 C-9.633000373840332,-2.805000066757202 10.89799976348877,-2.805000066757202 10.89799976348877,-2.805000066757202 C11.003999710083008,-2.812000036239624 11.111000061035156,-2.796999931335449 11.210000038146973,-2.759999990463257 C11.309000015258789,-2.7239999771118164 11.39900016784668,-2.6659998893737793 11.473999977111816,-2.5920000076293945 C11.550999641418457,-2.5179998874664307 11.609999656677246,-2.428999900817871 11.64799976348877,-2.3310000896453857 C11.687000274658203,-2.2330000400543213 11.706000328063965,-2.128000020980835 11.701000213623047,-2.0230000019073486 C11.701000213623047,-2.0230000019073486 11.701000213623047,0.8610000014305115 11.701000213623047,0.8610000014305115 C11.706999778747559,0.9670000076293945 11.690999984741211,1.0750000476837158 11.652999877929688,1.1740000247955322 C11.614999771118164,1.2730000019073486 11.555000305175781,1.3630000352859497 11.479000091552734,1.437999963760376 C11.402999877929688,1.5130000114440918 11.312999725341797,1.5709999799728394 11.213000297546387,1.6089999675750732 C11.11299991607666,1.6460000276565552 11.005000114440918,1.6640000343322754 10.89799976348877,1.6579999923706055 C10.89799976348877,1.6579999923706055 -9.633000373840332,1.6579999923706055 -9.633000373840332,1.6579999923706055 C-9.633000373840332,1.6579999923706055 -9.633000373840332,14.984000205993652 -9.633000373840332,14.984000205993652 C-9.633000373840332,14.984000205993652 14.112000465393066,14.984000205993652 14.112000465393066,14.984000205993652 C14.218999862670898,14.97700023651123 14.326000213623047,14.994000434875488 14.427000045776367,15.031999588012695 C14.527000427246094,15.069000244140625 14.619000434875488,15.128000259399414 14.694999694824219,15.204000473022461 C14.770999908447266,15.279000282287598 14.831000328063965,15.369999885559082 14.869000434875488,15.470999717712402 C14.906999588012695,15.569999694824219 14.92300033569336,15.677000045776367 14.916000366210938,15.784000396728516">
</path>
</g>
</g>
</g>
</svg>
</a>
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../../introduction/introduction.html">Introduction</a></li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Overview</li><li class="chapter-item expanded "><a href="../../dapps/0_xdappOverview.html"><strong aria-hidden="true">1.</strong> xDapps</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../dapps/1_defiBasics.html"><strong aria-hidden="true">1.1.</strong> Ecosystem Basics</a></li><li class="chapter-item expanded "><a href="../../dapps/2_crossChainInteroperability.html"><strong aria-hidden="true">1.2.</strong> Blockchain Interoperability</a></li><li class="chapter-item expanded "><a href="../../dapps/3_xdataxassets.html"><strong aria-hidden="true">1.3.</strong> xData &amp; xAssets</a></li><li class="chapter-item expanded "><a href="../../dapps/4_whatIsanXdapp.html"><strong aria-hidden="true">1.4.</strong> What is an xDapp?</a></li><li class="chapter-item expanded "><a href="../../dapps/5_advantages.html"><strong aria-hidden="true">1.5.</strong> Advantages of xDapps</a></li></ol></li><li class="chapter-item expanded "><a href="../../wormhole/0_wormholeOverview.html"><strong aria-hidden="true">2.</strong> Wormhole</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../wormhole/1_whatIsWormhole.html"><strong aria-hidden="true">2.1.</strong> What is Wormhole?</a></li><li class="chapter-item expanded "><a href="../../wormhole/2_architectureOverview.html"><strong aria-hidden="true">2.2.</strong> Architecture Overview</a></li><li class="chapter-item expanded "><a href="../../wormhole/3_coreLayerContracts.html"><strong aria-hidden="true">2.3.</strong> Core Layer Contracts</a></li><li class="chapter-item expanded "><a href="../../wormhole/4_vaa.html"><strong aria-hidden="true">2.4.</strong> VAA: Verified Action Approval</a></li><li class="chapter-item expanded "><a href="../../wormhole/5_guardianNetwork.html"><strong aria-hidden="true">2.5.</strong> Guardian Network</a></li><li class="chapter-item expanded "><a href="../../wormhole/6_relayers.html"><strong aria-hidden="true">2.6.</strong> Relayers</a></li><li class="chapter-item expanded "><a href="../../wormhole/7_xAssetBridge.html"><strong aria-hidden="true">2.7.</strong> xAsset Bridge</a></li><li class="chapter-item expanded "><a href="../../wormhole/8_wormchain.html"><strong aria-hidden="true">2.8.</strong> Wormchain</a></li></ol></li><li class="chapter-item expanded "><a href="../../wormhole/security.html"><strong aria-hidden="true">3.</strong> Security</a></li><li class="chapter-item expanded "><a href="../../dapps/architecture/0_dappDesign.html"><strong aria-hidden="true">4.</strong> xDapp Design</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../dapps/architecture/1_keyConsiderations.html"><strong aria-hidden="true">4.1.</strong> Key Considerations</a></li><li class="chapter-item expanded "><a href="../../dapps/architecture/2_ecosystems.html"><strong aria-hidden="true">4.2.</strong> Ecosystems</a></li><li class="chapter-item expanded "><a href="../../dapps/architecture/3_protocolDesign.html"><strong aria-hidden="true">4.3.</strong> Protocol Design</a></li><li class="chapter-item expanded "><a href="../../dapps/architecture/4_topology.html"><strong aria-hidden="true">4.4.</strong> Topology</a></li><li class="chapter-item expanded "><a href="../../dapps/architecture/5_relayers.html"><strong aria-hidden="true">4.5.</strong> Relayers</a></li><li class="spacer"></li></ol></li><li class="chapter-item expanded "><li class="part-title">Developing xDapps</li><li class="chapter-item expanded "><a href="../../technical/env/environments.html"><strong aria-hidden="true">5.</strong> Environment Setup</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../technical/env/tilt.html"><strong aria-hidden="true">5.1.</strong> Tilt (Devnet)</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../technical/env/troubleshooting.html"><strong aria-hidden="true">5.1.1.</strong> Troubleshooting</a></li></ol></li><li class="chapter-item expanded "><a href="../../technical/env/wlv.html"><strong aria-hidden="true">5.2.</strong> Wormhole Local Validator</a></li><li class="chapter-item expanded "><a href="../../technical/env/testnet.html"><strong aria-hidden="true">5.3.</strong> Testnet</a></li><li class="chapter-item expanded "><a href="../../technical/env/tooling.html"><strong aria-hidden="true">5.4.</strong> Tooling</a></li></ol></li><li class="chapter-item expanded "><a href="../../technical/overview.html"><strong aria-hidden="true">6.</strong> Contract Development</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../technical/evm/overview.html"><strong aria-hidden="true">6.1.</strong> EVM</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../technical/evm/coreLayer.html"><strong aria-hidden="true">6.1.1.</strong> Core Layer</a></li><li class="chapter-item expanded "><a href="../../technical/evm/tokenLayer.html"><strong aria-hidden="true">6.1.2.</strong> Token Bridge Module</a></li><li class="chapter-item expanded "><a href="../../technical/evm/nftLayer.html"><strong aria-hidden="true">6.1.3.</strong> NFT Bridge Module</a></li><li class="chapter-item expanded "><a href="../../technical/evm/relayer.html"><strong aria-hidden="true">6.1.4.</strong> Relayer Module</a></li><li class="chapter-item expanded "><a href="../../technical/evm/bestPractices.html" class="active"><strong aria-hidden="true">6.1.5.</strong> Best Practices</a></li><li class="chapter-item expanded "><a href="../../technical/evm/composableVerification.html"><strong aria-hidden="true">6.1.6.</strong> Composable Verification</a></li></ol></li><li class="chapter-item expanded "><a href="../../technical/solana/overview.html"><strong aria-hidden="true">6.2.</strong> Solana</a></li><li class="chapter-item expanded "><a href="../../technical/cosmos/overview.html"><strong aria-hidden="true">6.3.</strong> Cosmos</a></li><li class="chapter-item expanded "><a href="../../technical/algorand/overview.html"><strong aria-hidden="true">6.4.</strong> Algorand</a></li><li class="chapter-item expanded "><a href="../../technical/near/overview.html"><strong aria-hidden="true">6.5.</strong> Near</a></li><li class="chapter-item expanded "><a href="../../technical/aptos/overview.html"><strong aria-hidden="true">6.6.</strong> Aptos</a></li></ol></li><li class="chapter-item expanded "><a href="../../technical/relayer/overview.html"><strong aria-hidden="true">7.</strong> Relayers</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../technical/relayer/genericRelayer.html"><strong aria-hidden="true">7.1.</strong> Generic Relayers</a></li><li class="chapter-item expanded "><a href="../../technical/relayer/specializedRelayers.html"><strong aria-hidden="true">7.2.</strong> Specialized Relayers</a></li></ol></li><li class="chapter-item expanded "><a href="../../technical/typescript/overview.html"><strong aria-hidden="true">8.</strong> Wormhole Typescript SDK</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../technical/typescript/attestingToken.html"><strong aria-hidden="true">8.1.</strong> Token Registration</a></li><li class="chapter-item expanded "><a href="../../technical/typescript/tokenTransfer.html"><strong aria-hidden="true">8.2.</strong> Token Transfer Basics</a></li><li class="chapter-item expanded "><a href="../../technical/typescript/cross-ecosystem-transfer.html"><strong aria-hidden="true">8.3.</strong> Cross-Ecosystem Transfer</a></li><li class="chapter-item expanded "><a href="../../technical/typescript/using-relayer.html"><strong aria-hidden="true">8.4.</strong> Using Relayers</a></li><li class="spacer"></li></ol></li><li class="chapter-item expanded "><li class="part-title">Reference</li><li class="chapter-item expanded "><a href="../../reference/overview.html"><strong aria-hidden="true">9.</strong> Other Resources</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../reference/glossary.html"><strong aria-hidden="true">9.1.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="../../reference/usefulLinks.html"><strong aria-hidden="true">9.2.</strong> Useful Links</a></li><li class="chapter-item expanded "><a href="../../reference/contracts.html"><strong aria-hidden="true">9.3.</strong> Deployed Contracts</a></li><li class="chapter-item expanded "><a href="../../reference/rpcnodes.html"><strong aria-hidden="true">9.4.</strong> RPC Nodes</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents"
aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)"
aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S"
aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Wormhole Development Book</h1>
<div class="right-buttons">
<a href="../../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/wormhole-foundation/xdapp-book" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..."
aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function (link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<blockquote>
Warning: Some content may be outdated.
See <a href="https://docs.wormhole.com">docs.wormhole.com</a>
for up to date information
</blockquote>
<h1 id="best-practices"><a class="header" href="#best-practices">Best Practices</a></h1>
<p>The Wormhole contracts were designed in a manner such that composability is the default, but maximizing composability requires that xDapp developers follow certain conventions around the sending and receiving of messages.</p>
<h1 id="sending-messages"><a class="header" href="#sending-messages">Sending Messages</a></h1>
<p>When sending messages, you should follow the same paradigm as is used by the Wormhole modules, namely</p>
<ul>
<li>Don't couple the message emission to the message delivery</li>
<li>Pass through all the optional arguments (like nonce)</li>
<li>Always return the sequence</li>
</ul>
<h3 id="good-example"><a class="header" href="#good-example">Good Example</a></h3>
<pre><code class="language-solidity">// This function defines a super simple Wormhole 'module'.
// A module is just a piece of code which knows how to emit a composable message
// which can be utilized by other contracts.
function emitMyMessage(address intendedRecipient, uint32 nonce)
public payable returns (uint64 sequence) {
// Nonce is passed though to the core bridge.
// This allows other contracts to utilize it for batching or processing.
// intendedRecipient is key for composability!
// This field will allow the destination contract to enforce
// that the correct contract is submitting this VAA.
// Here we encode the payload into our wire format.
// There's basically always a corresponding decode/parse function as well.
bytes myMessage = abi.encode(&quot;My Message to &quot; + intendedRecipient);
// consistency level 200 means instant emission
sequence = core_bridge.publishMessage(nonce, myMessage, 200);
// The sequence is passed back to the caller, which can be useful relay information.
// Relaying is not done here, because it would 'lock' others into the same relay mechanism.
}
// This is the portion of the code which deals with composition and delivery.
// Its job is to string together multiple modules, and ensure they get relayed
// This code can be private or public, because it's tightly coupled to your application.
// Do whatever you need to here.
function sendMyMessage() public payable {
// First, emit a message intended for MY_OTHER_CONTRACT with nonce 1.
// Because processMyMessage enforces that msg.sender must equal the intendedRecipient,
// no one but MY_OTHER_CONTRACT will be able to call processMyMessage
// with the message emitted from this transaction.
// However, another contract could call emitMyMessage in a different transaction
// using their own address as the recipient.
// This allows for composability of the module logic while still being secure!
emitMyMessage(MY_OTHER_CONTRACT, 1);
// Suppose I also want to send tokens to my contract on the OTHER_CHAIN
// Because transferTokensWithPayload is a composable message, I can include it.
// Because the nonce of both these messages is 1, they will be combined into a batch VAA.
// NOTE: transferTokens (the basic transfer) is NOT considered a composable message
token_bridge.transferTokensWithPayload(SOME_TOKEN, SOME_AMOUNT, OTHER_CHAIN, MY_OTHER_CONTRACT,
1, null);
// Lastly, I request that the batch for nonce 1 be delivered to MY_OTHER_CONTRACT
ICoreRelayer.DeliveryRequest memory request = ICoreRelayer.DeliveryRequest(
OTHER_CHAIN, //targetChain
MY_OTHER_CONTRACT, //targetAddress
MY_OTHER_CONTRACT_CONTRACT, //refundAddress
msg.value, //computeBudget
0, //applicationBudget
relayer_contract.getDefaultRelayParams() //relayerParams
);
relayer.requestDelivery{value: msg.value}(
request, 1, relayer.getDefaultRelayProvider()
);
}
</code></pre>
<h1 id="receiving-messages"><a class="header" href="#receiving-messages">Receiving Messages</a></h1>
<p>The best practices for receiving messages employ similar concepts. You should keep in mind that other contracts might want to integrate with your specific logic. As such, you shouldn't tie your verification logic to the delivery mechanism of your VAAs, and you should also give external integrators a safe way to compose with your module.</p>
<h3 id="critical"><a class="header" href="#critical"><strong><em>Critical</em></strong></a></h3>
<ul>
<li>
<p>Always verify that the emitterAddress of the VAA comes from a contract you trust.</p>
</li>
<li>
<p>If the message should not be allowed to be 'replayed', immediately mark its hash as processed.</p>
</li>
<li>
<p>If your VAAs aren't replayable, you almost always want to include and enforce an intended recipient. Otherwise anyone can call your verify function directly with the single VAA, which will make life much harder for you and your integrators who want to process multiple VAAs at once. This is referred to as a 'scoop' exploit.</p>
</li>
</ul>
<h3 id="composability"><a class="header" href="#composability">Composability</a></h3>
<ul>
<li>When processing a VAA, always treat the messages as single VAAs. Destructuring batch VAAs is the responsibility of the integrator.</li>
<li>Once you have the function written to verify your message, pretend you are an external integrator.</li>
</ul>
<h3 id="good-example-1"><a class="header" href="#good-example-1">Good Example</a></h3>
<pre><code class="language-solidity">// Verification accepts a single VAA, and is publicly callable.
function processMyMessage(bytes32 memory VAA) public {
// This call accepts single VAAs and headless VAAs
(IWormhole.VM memory vm, bool valid, string memory reason) =
core_bridge.parseAndVerifyVM(VAA);
// Ensure core contract verification succeeded.
require(valid, reason);
// Ensure the emitterAddress of this VAA is a trusted address
require(myTrustedContracts[vm.emitterChainId] ==
vm.emitterAddress, &quot;Invalid Emitter Address!&quot;);
// Check that the VAA hasn't already been processed (replay protection)
require(!processedMessages[vm.hash], &quot;Message already processed&quot;);
// Check that the contract which is processing this VAA is the intendedRecipient
// If the two aren't equal, this VAA may have bypassed its intended entrypoint.
// This exploit is referred to as 'scooping'.
require(parseIntendedRecipient(vm.payload) == msg.sender);
// Add the VAA to processed messages so it can't be replayed
// you can alternatively rely on the replay protection
// of something like transferWithPayload from the Token Bridge module
processedMessages[vm.hash] = true
// The message content can now be trusted.
doBusinessLogic(vm.payload)
}
//This is the function which receives the the VAA from the CoreRelayer contract
function receiveWormholeMessages(bytes[] memory whMessages, bytes[] memory otherData)
public payable override onlyRelayerContract {
// I know from sendMyMessage that the first VAA should be a token bridge VAA,
// so let's hand that off to the token bridge module.
bytes vaaData = token_bridge.completeTransferWithPayload(whMessages[0]);
// The second VAA is my message, let's hand that off to my module.
processMyMessage(vm2.payloads[1]);
}
modifier onlyRelayerContract() {
require(msg.sender == CORE_RELAYER_CONTRACT_ADDRESS, &quot;msg.sender is not CoreRelayer contract.&quot;);
_;
}
</code></pre>
<!--
TODO these are not actually functioning examples and some of the interactions are incorrect. Demonstrates the concept.
>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../../technical/evm/relayer.html" class="mobile-nav-chapters previous"
title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../../technical/evm/composableVerification.html" class="mobile-nav-chapters next"
title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../../technical/evm/relayer.html" class="nav-chapters previous" title="Previous chapter"
aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../../technical/evm/composableVerification.html" class="nav-chapters next" title="Next chapter"
aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
<script type="text/javascript" src="../../src/static/solidity.min.js"></script>
</body>
</html>