Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div class="container">
  <h5>Estimate transaction fee</h5>
  Transfer 1 wei vet & 1 wei vtho cost in different priority
  <div class="card-group">
    <div class="card">
      <div class="card-body">
        <h5 class="card-title">Regular</h5>
        <p class="card-text text-primary" id="regular">-- VTHO</p>
      </div>
      <div class="card-footer">
        <small class="text-muted" id="regularGas">GasPriceCoef: 0</small>
      </div>
    </div>
    <div class="card">
      <div class="card-body">
        <h5 class="card-title">Medium</h5>
        <p class="card-text text-success" id="medium">-- VTHO</p>

      </div>
      <div class="card-footer">
        <small class="text-muted">GasPriceCoef: 85</small>
      </div>
    </div>
    <div class="card">
      <div class="card-body">
        <h5 class="card-title">High</h5>
        <p class="card-text text-info" id="high">-- VTHO</p>
      </div>
      <div class="card-footer">
        <small class="text-muted">GasPriceCoef: 255</small>
      </div>
    </div>
  </div>
  <br>
  <pre id="bgp">BaseGasePrice: --</pre>
  <pre id="vmUsed">Vm gasUsed: --</pre>
  <pre id="intrinsic">IntrinsicGas: --</pre>
  <pre id="totalGas">Total Gas: --</pre>
  <a href="https://docs.vechain.org/thor/learn/transaction-calculation.html">Ref: Transaction fee calculation</a>
</div>
              
            
!

CSS

              
                .container {
  width: 80%;
}

              
            
!

JS

              
                const connex = new Connex({
  node: "https://testnet.veblocks.net/",
  network: "test"
});
const transferABI = {
  constant: false,
  inputs: [
    {
      name: "_to",
      type: "address"
    },
    {
      name: "_amount",
      type: "uint256"
    }
  ],
  name: "transfer",
  outputs: [
    {
      name: "success",
      type: "bool"
    }
  ],
  payable: false,
  stateMutability: "nonpayable",
  type: "function"
};

const paramsABI = {
  constant: true,
  inputs: [
    {
      name: "_key",
      type: "bytes32"
    }
  ],
  name: "get",
  outputs: [
    {
      name: "",
      type: "uint256"
    }
  ],
  payable: false,
  stateMutability: "view",
  type: "function"
};

async function getBaseGasPrice() {
  const baseGasPriceMethod = connex.thor
    // params contract address
    .account("0x0000000000000000000000000000506172616d73")
    .method(paramsABI);
  const outputs = await baseGasPriceMethod.call(
    //0x000000…696365 is the key of baseGasPrice https://docs.vechain.org/others/miscellaneous.html#key-of-governance-params
    "0x000000000000000000000000000000000000626173652d6761732d7072696365"
  );

  return outputs.decoded[0];
}

//get vm gas used
async function vmGasUsed(clauses) {
  const exp = connex.thor.explain(clauses);
  const outputs = await exp
    // Set maximum gas
    .gas(20000000)
    // Set caller
    .caller("0x8a259d8684E88e063EaA2213a7a390A725065c65")
    .execute();

  return outputs.reduce((sum, out) => sum + out.gasUsed, 0);
}

async function estimateTxFee() {
  //Create clauses of transferring VET & VTHO
  const transferMethod = connex.thor
    .account("0x0000000000000000000000000000456E65726779")
    .method(transferABI);
  // Alice's address transfer 1 wei vtho
  const vthoClause = transferMethod.asClause(
    "0xd3ae78222beadb038203be21ed5ce7c9b1bff602",
    1
  );
  //Alice address transfer 1 wei vet
  const vetClause = {
    to: "0xd3ae78222beadb038203be21ed5ce7c9b1bff602",
    value: 1,
    data: "0x486170707920636f64696e6720f09f8e89"
  };

  const clauses = [vetClause, vthoClause];

  const intrinsic = intrinsicGas(clauses);
  const baseGasPrice = await getBaseGasPrice();
  const vmUsed = await vmGasUsed(clauses);

  updateUI(intrinsic, baseGasPrice, vmUsed);
}

estimateTxFee();

function updateUI(intrinsic, baseGasPrice, vmUsed) {
  //adding some extra gas to make sure the transaction go through
  const gas = new BigNumber(intrinsic).plus(vmUsed).plus(15000);
  //priority regular = gasPriceCoef 0/255
  const regularCost = calcFee(gas, baseGasPrice, 0).toFixed(2);
  //priority medium = gasPriceCoef 85/255
  const mediumCost = calcFee(gas, baseGasPrice, 85).toFixed(2);
  //priority high = gasPriceCoef 255/255
  const highCost = calcFee(gas, baseGasPrice, 255).toFixed(2);

  document.getElementById("regular").innerText = regularCost + " VTHO";
  document.getElementById("medium").innerText = mediumCost + " VTHO";
  document.getElementById("high").innerText = highCost + " VTHO";

  const vtho = BigNumber(1e18).dividedBy(baseGasPrice);

  document.getElementById("totalGas").innerText = "Total Gas: " + gas + " gas";
  document.getElementById("bgp").innerText =
    "BaseGasePrice:" + baseGasPrice + " (1 VTHO = " + vtho + " gas)";
  document.getElementById("vmUsed").innerText =
    "Vm gasUsed: " + vmUsed + " gas";
  document.getElementById("intrinsic").innerText =
    "IntrinsicGas: " + intrinsic + " gas";
}

function intrinsicGas(clauses) {
  const txGas = 5000;
  const clauseGas = 16000;
  const clauseGasContractCreation = 48000;

  if (clauses.length === 0) {
    return txGas + clauseGas;
  }

  return clauses.reduce((sum, c) => {
    if (c.to) {
      sum += clauseGas;
    } else {
      sum += clauseGasContractCreation;
    }
    sum += dataGas(c.data);
    return sum;
  }, txGas);
}

function dataGas(data) {
  const zgas = 4;
  const nzgas = 68;

  let sum = 0;
  for (let i = 2; i < data.length; i += 2) {
    if (data.substr(i, 2) === "00") {
      sum += zgas;
    } else {
      sum += nzgas;
    }
  }
  return sum;
}

function calcFee(gas, baseGasPrice, gasPriceCoef) {
  return new BigNumber(baseGasPrice)
    .times(gasPriceCoef)
    .idiv(255)
    .plus(baseGasPrice)
    .times(gas)
    .dividedBy(1e18);
}

              
            
!
999px

Console