Browse Source

Merge pull request #59 from Bucko13/html-meta

insert post meta into guide template
nov-updates
Buck Perley 7 years ago
committed by GitHub
parent
commit
3458b20d47
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      guides.html
  2. 22
      guides/crowdfund-tx.html
  3. 2
      page-templates/guides-archive.html
  4. 6
      page-templates/guides-template.html
  5. 17
      utils/createHTML.js

2
guides.html

@ -6,7 +6,7 @@
<meta name="description" content="">
<meta name="author" content="">
<title>bcoin | Extending Bitcoin into Enterprise & Production</title>
<title>Bcoin Guides | Learning Bitcoin and Building Apps with Bitcoin</title>
<!-- Favicons -->
<!-- old

22
guides/crowdfund-tx.html

@ -3,10 +3,10 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<meta name="description" content="Learn how SIGHASH flags work in Bitcoin by building out a custom crowdfunding transaction that lets anyone add their own inputs to a transaction with a fixed output.">
<meta name="author" content="Buck Perley">
<title>bcoin | Extending Bitcoin into Enterprise & Production</title>
<title>Create a Crowdfunding Transaction</title>
<!-- Favicons -->
<!-- old
@ -318,11 +318,7 @@
<p>ALL|ANYONECANPAY<br>This construction can be used to make a &quot;crowdfunding”-style transaction. Someone attempting to raise funds can construct a transaction with a single output. The single output pays the &quot;goal&quot; amount to the fundraiser. Such a transaction is obviously not valid, as it has no inputs. However, others can now amend it by adding an input of their own, as a donation. They sign their own input with ALL|ANYONECANPAY. Unless enough inputs are gathered to reach the value of the output, the transaction is invalid. Each donation is a &quot;pledge,&quot; which cannot be collected by the fundraiser until the entire goal amount is raised.</p>
</blockquote>
<h2 id="the-code">The Code</h2><p>We&#39;ll walk through the steps of creating the transaction first without any wallet database or node running. Then we&#39;ll do the same thing using bcoin&#39;s walletdb to manage the keys to see how it would work in a more realistic application (skip to <a href="#version-2-using-the-bcoin-wallet-system">Version 2</a>) further in the guide to check it out). At the end, we&#39;ll put out some ideas of how these can be built upon for a more robust, production ready application. (If this is something you&#39;d be interested in building, <a href="http://bcoin.io/slack-signup.html">get in touch</a>!). If you want to see the code, checkout the <a href="https://github.com/Bucko13/bitcoin-fundraise">repo on github</a>.</p>
<<<<<<< HEAD
<p>If you&#39;re not comfortable with key management, coin selection, and how transactions are constructed, checkout the tutorial on <a href="http://bcoin.io/guides/working-with-txs.html">working with transactions</a> first.</p>
=======
<p>If you&#39;re not comfortable with key management, coin selection, and how transactions are constructed, checkout the tutorial on <a href="https://github.com/bcoin-org/bcoin/blob/master/docs/Working-with-transactions.md">working with transactions</a> first.</p>
>>>>>>> staging
<h3 id="version-1--manual-key-management">Version 1 - Manual Key Management</h3><h4 id="step-1-setup">Step 1: Setup</h4><p>Let&#39;s first start by importing the right tools, setting up some constants, and creating our keychains. (make sure you&#39;ve installed the latest version of bcoin into your project with <code>npm install bcoin</code>).</p>
<p>Note that we&#39;re setting the fundingTarget and amountToFund as constants for simplicity, but they could be set based on user input or some other variable circumstances.</p>
<pre class="snippet line-numbers language-javascript"><code class="line-numbers language-javascript"><span class="token string">'use strict'</span><span class="token punctuation">;</span>
@ -404,11 +400,7 @@
<span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token property">"1"</span><span class="token operator">:</span> <span class="token punctuation">[</span>...<span class="token punctuation">]</span>
<<<<<<< HEAD
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="step-3-prepare-your-coins">Step 3: Prepare your Coins</h4><p>Above, we just funded our funder accounts with a single 5BTC outpoint. This means that the next transaction funded from these accounts can only use that one outpoint (or <em>coin</em>) as an input and send the remainder back as change. Remember, in Bitcoin the way you send funds is you fund a transaction with a full UTXO (in this case we only have one worth 5BTC available to our keychains) and then send the change back to yourself as an additional output. Since ALL|ANYONECANPAY transactions mean a fixed output, you can&#39;t add new change outputs without other signatures becoming invalid which means we need a coin available equal to the amount we want to contribute to the crowdfund.</p>
=======
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="step-4-prepare-your-coins">Step 4: Prepare your Coins</h4><p>Above, we just funded our funder accounts with a single 5BTC outpoint. This means that the next transaction funded from these accounts can only use that one outpoint (or <em>coin</em>) as an input and send the remainder back as change. Remember, in Bitcoin the way you send funds is you fund a transaction with a full UTXO (in this case we only have one worth 5BTC available to our keychains) and then send the change back to yourself as an additional output. Since ALL|ANYONECANPAY transactions mean a fixed output, you can&#39;t add new change outputs without other signatures becoming invalid which means we need a coin available equal to the amount we want to contribute to the crowdfund.</p>
>>>>>>> staging
<p>So what we want to do is have each funder create a coin (UTXO) with the value of what they want to donate.</p>
<p>The first thing we need to do make this work is calculate what the input will be. In our examples we are assuming that the funders cover the fee. Since different keyrings can be using different transaction types of different sizes (p2sh, multisig, etc.), we need a utility to calculate how much the fee should be for that input and add that to the amount to fund with.</p>
<h5 id="utility-functions">Utility functions</h5><p>We&#39;ll need some utility functions to help us out. It&#39;s nice to split these out separate from our main operations since we&#39;ll actually be reusing some of the functionality.</p>
@ -509,11 +501,7 @@
...
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token property">"1"</span><span class="token operator">:</span> <span class="token punctuation">[</span>...<span class="token punctuation">]</span>
<<<<<<< HEAD
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="step-4-construct-the-transaction">Step 4: Construct the Transaction</h4><p>Now that we&#39;ve got our tools and coins ready, we can start to build the transaction!</p>
=======
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="step-6-construct-the-transaction">Step 6: Construct the Transaction</h4><p>Now that we&#39;ve got our tools and coins ready, we can start to build the transaction!</p>
>>>>>>> staging
<pre class="snippet line-numbers language-javascript"><code class="line-numbers language-javascript"><span class="token keyword">const</span> composeCrowdfund <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">composeCrowdfund</span><span class="token punctuation">(</span>coins<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true">//...</span>
@ -700,11 +688,7 @@
<span class="token function">composeWalletCrowdfund</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>myCrowdfundTx <span class="token operator">=</span><span class="token operator">></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Transaction broadcast: '</span><span class="token punctuation">,</span> myCrowdfundTx<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token keyword">catch</span><span class="token punctuation">(</span>e <span class="token operator">=</span><span class="token operator">></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'There was a problem: '</span><span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><p>And there you have it! If you were doing this on testnet, your <code>fundeeWallet</code> should now be 1BTC richer. If you&#39;re on a simnet or regtest network, you&#39;ll have to mine a block with your transactions to get those funds confirmed. Also note that, unless you have exact change coins, there will be 3 transactions that need to be confirmed: one each for the wallets that are splitting coins, and one for the crowdfund transaction.</p>
<<<<<<< HEAD
<h2 id="how-to-extend-and-improve">How to Extend and Improve</h2><p>These examples are obviously pretty basic, but they should give you an idea of how to use Bitcoin&#39;s scripting to build out the foundation for more complex applications. Here are some ideas on how you could build on top of these examples and get closer to a production ready application.</p>
=======
<h2 id="how-to-build-it-out">How to Build it Out</h2><p>These examples are obviously pretty basic, but they should give you an idea of how to use Bitcoin&#39;s scripting to build out the foundation for more complex applications. Here are some ideas on how you could build on top of these examples and get closer to a production ready application.</p>
>>>>>>> staging
<ul>
<li>More flexible contribution scheme (currently it&#39;s just 2 funders that split the amount evenly). E.g. custom number of contributers, custom contribution amount, etc.</li>
<li>UX to let people interact with the transaction via a browser</li>

2
page-templates/guides-archive.html

@ -6,7 +6,7 @@
<meta name="description" content="">
<meta name="author" content="">
<title>bcoin | Extending Bitcoin into Enterprise & Production</title>
<title>Bcoin Guides | Learning Bitcoin and Building Apps with Bcoin</title>
<!-- Favicons -->
<!-- old

6
page-templates/guides-template.txt → page-templates/guides-template.html

@ -3,10 +3,10 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<meta name="description" content="<%= description %>">
<meta name="author" content="<%= author %>">
<title>bcoin | Extending Bitcoin into Enterprise & Production</title>
<title>Bcoin Guide | <%= title %></title>
<!-- Favicons -->
<!-- old

17
utils/createHTML.js

@ -3,6 +3,7 @@ const fs = require('fs');
const path = require('path');
const Prism = require('prismjs');
const PrismLanguages = require('prism-languages');
const _ = require('underscore');
const generateSidebar = require('./generateSidebar.js');
const helpers = require('./helpers');
@ -49,6 +50,7 @@ const createHTML = async function createHTML(markdownFile, htmlFile, author, pos
renderer.code = function (code, language) {
if (language === 'post-author') {
// only return code block if wasn't set by argument
author = code;
return postMeta ? '' : getPostMeta(code);
}
@ -75,7 +77,7 @@ const createHTML = async function createHTML(markdownFile, htmlFile, author, pos
// Assemble guide text container
let blogText = marked(markdownString);
let template = fs.readFileSync(path.resolve(templatesDir, 'guides-template.txt'))
let guideText = fs.readFileSync(path.resolve(templatesDir, 'guides-template.html'))
.toString();
// these constants are comment text that mark the start
@ -86,14 +88,21 @@ const createHTML = async function createHTML(markdownFile, htmlFile, author, pos
// generate sidebar and insert into our page template
const sidebarText = await generateSidebar('guides', rootDir);
template = insertToTemplate(template, SIDEBAR_START, sidebarText);
guideText = insertToTemplate(guideText, SIDEBAR_START, sidebarText);
// insert the guide text into our template
template = insertToTemplate(template, GUIDE_START, blogText);
guideText = insertToTemplate(guideText, GUIDE_START, blogText);
const guideTemplate = _.template(guideText);
const postInfo = {
title: guideTitle,
author,
description: guideDescription
}
// create the html file for final output
return new Promise((resolve, reject) => {
fs.writeFile(htmlFile, template, {flags: 'w+'}, (err) => {
fs.writeFile(htmlFile, guideTemplate(postInfo), {flags: 'w+'}, (err) => {
if (err) reject(err);
resolve(htmlFile)
});

Loading…
Cancel
Save