Tutorial: Intro to jigs that run on Bitcoin: Mocknet and Web Console

A jig is an interactive object, run on Bitcoin.

People interact with jigs by giving them instructions. And, jigs also interact with each other. With jigs, you can build almost anything you can dream up as digital property you can own.

You might create tokens, contracts, and interfaces. Jigs can power document signing, logistics, even voting in elections. The most fun, of course, will be video game items and lifelike digital pets!

RUN is an open-source software development kit (SDK) that uploads code to the Bitcoin blockchain. You’ll use it to create and update jigs.

Getting Started

By using object-oriented programming, you can write computer code to describe interactions between objects.

The cool thing about jigs is that many people all around the world already have enough knowledge to build jigs since they’re familiar with common tools like JavaScript. RUN abstracts away a lot of the Bitcoin-specific details, so that you can focus on the code for the smart objects themselves.

Imagine the classic example of a car. It’s got wheels and an engine. It can perform actions like driving, and it has attributes like red paint color:

The car is owned by someone. You can tell it to do things like turn on the windshield wipers, and you can sell it when you want to get a new one.

Jigs have many of the same traits as cars with a key difference: they’re described by code as digital property.

Setting up your browser

Right-click on this link for RUN's homepage ➞ run.network. Then left-click Open link in new window.

Click and drag the window to arrange two browser windows side-by-side so that you can see both RUN's homepage and this tutorial at the same time:

Exploring jigs

To discover your first jigs, look near the top right of the page in the navbar and click Explorer:

You’re going to search for a bitcoin address: 14aJe8iM3HopTwa44Ed5ZQq2UxdDvrEMXo. Double-click the address to select it. Then copy and paste it into the Explorer search box.

This bitcoin address holds three jigs, and you can also see when they were last updated:

Locate the Dragon jig in the list, and click on the last updated time. Notice that the search field has been changed to a transaction ID: f97…bbb. That is a bitcoin transaction:

The transaction has a method call, init(name, age). That means the latest transaction on the jig was to create a new dragon and assign a couple of properties.

Bitcoin transactions have a memo field where people can put extra details about a transaction just like the memo line on a physical written check:

The protocol data for RUN is stored there in the memo field, or op_return, of the transaction.

Each time you want to update a jig, you’ll send a new transaction with the method call.

Jigs are property that individuals own. Only the owner of the jig can update it because only the owner of a Bitcoin output can spend it. Your jigs are just as secure as your bitcoins.

Coding in the Web Console

The quickest way to play around with RUN is to use your browser’s Web Console. In this tutorial, you’ll use Firefox as a playground. But you could use a different browser if you need to: Chrome, Opera, Safari, and even Edge. RUN works everywhere. 😎

To pop open the Web Console, press Control-Shift-K on Windows or Command-Option-K on macOS.

Note: If you use a different web browser than Firefox, the keyboard shortcut could be different.

You’ll see a command prompt chevron where you can type commands:

The Console is a lot like the desktop app Terminal, if you’ve ever used that. You type commands into the command prompt and press Return to submit them. The Console is also where any errors in your code will show up.

Create a new instance of Run by typing this code next to the blue chevron:

const run = new Run({ network: 'mock' })

The Mock network keeps all the Bitcoin transactions local to your machine. So while everything that happens on the Mock network is a simulation, you’re still using real, signed Bitcoin transactions.

Press Return to execute the line of code:

The Console displays a new line with the result, or return value, of whatever code you executed. When there is no return value, the Console shows, undefined. But don’t worry! Your code is stored safely in the Console session. It is telling you that nothing was returned and that the last command didn’t cause an error. You’re ready to continue. ✔️

Pro Tip: Whenever you want to make a new line or jump to the next line, without executing the code, press Shift-Return. Use that when you want to write more code on another line without executing the first. Go ahead and try it. The cursor will move one line down. The Console isn’t picky about empty lines, so you can add as many spacing lines as you like between lines of code.

Uploading a jig

Earlier you learned that method calls on a jig are stored in a Bitcoin transaction. Well, the class definition of a jig is stored in the same way. So the class definition transaction is like the seed of a tree and the method calls are the branches that grow out from the original transaction:

Copy and paste this code into the Console to create your first jig:

class Dragon extends Jig {
  setName(name) {
    this.name = name

Press Return to submit it.

Now is the moment you’ve been waiting for, you’re about to put code into Bitcoin. Type the following code:

const dragon = new Dragon()

Press Return to submit it. And that’s it!

Behind the scenes, several things are happening. You created a new instance of the Dragon class--that much is clear. But RUN has done the heavy lifting for you.

Advanced programmers: The definition of Dragon has been stored as JSON in the output of a Bitcoin transaction. Both the class definition and the new instance are stored in the same Bitcoin transaction on different outputs. RUN is smart enough to save money by packaging multiple jig instructions into a single transaction, and allowing the classes and instances to operate independently in the future.

Beginner programmers:

Programming Basics

If you’re new to programming, I’ll quickly introduce some of the vocabulary. Don’t worry if it doesn’t sink in immediately. The jargon will seem dense at first. But over time, you’ll pick up more. The best way to learn is by doing. So, with each time you play around with it, the programming terms will make more sense.

Programmers talk about the blueprint or general idea of a car as the class definition. Then many instances can exist, driving around in the world.

To differentiate between the two:

  • Class definitions use a capital first letter, Car
  • Instances use a lowercase first letter, car

The class definition, on the left, is what all cars share. The instance, on the right, is a person’s car.

You can select any name you like for an instance:

const myCar = new Car()
const eleanor = new Car()
const batMobile = new Car()

The common thing is that instances use a lowercase first letter. If you want to have a second or third word in the instance name, capitalize the first letter of each of the following words. That is called, camel case: heresAnEntireSentenceWrittenInCamelCase.

The instance name isn’t recorded by the car itself; the instance name is just how you refer to it in code. If you want the car to remember its name and to be able to ask the computer to tell you the car’s name, you’re going to have to set a property on the car. But first, let’s back up and think about, what really is a car, anyway?

Cars have attributes and actions. An attribute would be the car’s color. And an action would be like when you tell the car to drive. Here’s a quick explanation for both:

  • For an attribute, like color, developers refer to that as a property. You set properties with an assignment: car.color = "red". Then, you check on the value of a property: car.color … and the computer responds: "red".
  • For an action, like drive(howFast), programmers refer to that as a method. You call a method: car.drive(55). The thing inside the parentheses, (in here), is referred to as a parameter. You use a parameter to pass something into the method. Methods can also have multiple parameters: playMusic(song, volume). In that method, you’re passing in settings to adjust the stereo system.

When you want to manufacture a car, you call the initializer, alternatively known as the constructor: new Car(). The initializer is a method, so it can accept parameters:

// 1
class Car {
  // 2
  init(color) {
    // 3
    this.color = color

Here’s what’s happening:

  1. You annotate your code with comments using two forward slashes, //. Then the rest of that line following the comment won’t affect your code. Class definitions are preceded by the keyword, class, and they use a capital first letter. You enclose the code inside both classes and methods with curly braces, { }. Inside a class or method, you indent the lines to make the code easier to read so that people can differentiate what belongs inside.
  2. The initializer for Car accepts one parameter, color. You’ll call an initializer like this: const car = new Car("blue"). With that, you’re the owner of a shiny blue car and you can talk tell your friends about, “my blue car”. The const keyword is short for constant reference to a value. It means that the instance, car, will always be the same object. While you cannot reassign it to a different object, you can still change its properties.
  3. The keyword, this, is a reference to the object itself. So the initializer takes the color that you pass in and then sets the color property on the object. The property on the left side of the equals sign is what you are assigning the value on the right side: property = value.

With that short introduction, you’ve gotten a taste of JavaScript. You’re well on your way towards building jigs. Plus, you can always hop back to this section when you stumble across some code you don’t yet understand.

You can point to any jig or class definition by its location. The location is the pair of a transaction ID and an output index together, separated by an underscore: transactionID_outputIndex

Type the following code:

console.log('class:    ', Dragon.location)
console.log('instance: ', dragon.location)

Pro Tip: You can execute these lines separately by pressing Return after each one, or you can practice adding multiple lines of code before executing by pressing Shift-Return before typing the second line.

Console will print out the locations of the two:

You can see that the class definition and the instance have the same transaction ID (the long first part—something like, "155…2bf") but have separate output indexes (the short second part, "o1" & "o2").

If you’re not a programmer all this probably sounds über nerdy. The important takeaway is that both the description of the dragon (the class definition) and your actual live dragon (the instance) are stored on the Bitcoin blockchain. Or, as we like to say, the data is on-chain.

Updating a jig

Now that you’ve uploaded the class definition and created the first instance, the next step is to perform some actions with your jig. To perform an action, you call a method. You defined the Dragon class with a single method, setName(name).

To call the method is as easy as can be. Just type the following code:


You’re calling a method on the instance of the Dragon class — the individual dragon — called dragon, to give it a friendly name. The method call is just another Bitcoin transaction.

The value of a jig is defined by all the modifications or updates that have happened to it over time. To calculate and verify the current state of a jig, your wallet will replay the history of transactions from the beginning, when the jig was initialized.

RUN has built-in protection to keep you from publishing a transaction that wouldn’t be accepted.

But, you may want to double-check whether you’ve made your update correctly. You can access a property of a jig by typing the following code into the Console:


The console will show you the result:

And what about if you wanted to check that the jig had indeed been updated in a new transaction? Type the following code:


The console shows you the result:

So the transaction ID is now different for location than it was before. If you want to access the original location where the jig was first defined, use the origin. The jig is fully expressed by all the updates from its origin, leading up to the current location.

Where to go from here?

Congratulations on writing your first jig.

From run.network, look near the top right of the page in the navbar and click Docs:

Use the documentation as a reference along your journey. Over time, you’ll get to know all the features in the RUN SDK.

In this tutorial, you used the Mockchain to speed up development. As a challenge, try moving over to Mainnet. If you are successful, not only will you be able to see your jig on the RUN Explorer, you’ll also be able to see your bitcoin address and transactions on a block explorer like WhatsOnChain.

For a guided journey, head on over to the next tutorial: Mainnet, Part 1 with WhatsOnChain →

We’re at the beginning of something very big here. You’re on the ground level of a new platform. Now anyone can build interactive objects that run on Bitcoin. Jigs might just become your new familiar friends.