taro

package module
v0.1.1-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2022 License: MIT Imports: 50 Imported by: 0

README

Taro

The Taro Daemon tarod implements the Taro protocol for issuing assets on the Bitcoin blockchain. Taro leverages Taproot transactions to commit to newly created assets and their transfers in an efficient and scalable manner. Multiple assets can be created and transferred in a single bitcoin UTXO, while witness data is transacted and kept off-chain.

Features:

  • Mint assets
  • Send and receive assets
  • Export and import Taro proofs
  • Create and manage profiles

How it works:

When minting a new asset, Taro will generate the relevant witness data, assign the asset to a key held by you and publish the corresponding bitcoin UTXO -- the minting transaction.

The outpoint this minting transaction consumes becomes the genesis_point of the newly minted asset, acting as its unique identifier. Assets can be spent to a new recipient, who provides the sender with the necessary information encoded in their Taro address.

To transact assets, the witnesses in the prior Taro transaction are recommitted into one or multiple taproot outputs while the necessary witness data is passed to the recipient. Similar to bitcoin transactions, the remaining balance is spent back to the sender as a change output.

Learn more about the Taro protocol.

Architecture:

Taro is implemented as the Taro Daemon tarod and the Taro Command Line Interface tarocli. Additionally, tarod exposes a GRPC interface to allow for a direct integration into applications.

Taro leverages several LND features including the Taproot wallet and signing capabilities. These facilities are accessed through LND’s GRPC.

The Taro stack:

Bitcoin blockchain backend <-> LND <-> Taro

Custody of Taro assets is segmented across LND and Taro to maximize security. LND holds the private key, which has had a taproot tweak applied to it, controlling the bitcoin UTXO holding the Taro asset. The taproot tweak on the other hand is held by Taro. This increases the requirements for asset recovery as both the internal key as well as the taproot tweak are necessary to spend the output. This prevents LND from accidentally burning Taro assets.

Prerequisites:

Taro requires LND (compiled on the latest master branch with the relevant tags, see below) to be synced and running on the same Bitcoin network as Taro (e.g. regtest, simnet, testnet3). RPC connections need to be accepted and a valid macaroon needs to be present.

git clone https://github.com/lightningnetwork/lnd.git
cd lnd 
make install tags="signrpc walletrpc chainrpc invoicesrpc"

Installation:

From source:

Compile Taro from source by cloning this repository. Go version 1.18 or higher is required.

git clone https://github.com/lightninglabs/taro.git
cd taro
make install

Initialization:

Run Taro with the command tarod. Specify how Taro can reach LND and what network to run Taro with by passing it additional flags.

# Ensure lnd and its bitcoind/btcd backend are running first.
tarod --network=testnet --debuglevel=debug --lnd.host=localhost:10009 --lnd.macaroonpath=~/.lnd/data/chain/bitcoin/testnet/admin.macaroon --lnd.tlspath=~/.lnd/tls.cert

Usage:

See a full list of options by executing:

tarod --help

Use tarocli to interact with tarod

tarocli assets mint --type normal --name fantasycoin --supply 100 --meta "fantastic money" --skip_batch
tarocli assets list
tarocli addrs new --genesis_bootstrap_info bab08407[...]129bf6d0 --amt 21
tarocli assets send --addr tarotb1q[...]tywpre3a

Development

API

Taro exposes a GRPC (port 10029) and a REST (port 8089) API. Connections are encrypted with TLS and authenticated using macaroons.

Mainnet

The current codebase does not support the Bitcoin mainnet. Patching the code to run on mainnet will very likely lead to loss of funds (both the minted assets and the BTC UTXO) as things will break or change in the future.

Submit feature requests

The GitHub issue tracker can be used to request specific improvements or report bugs.

Join us on Slack

Join us in the Lightning Labs Slack and join the #taro channel to ask questions and interact with the community.

Documentation

Index

Constants

View Source
const (
	// AppMajor defines the major version of this binary.
	AppMajor uint = 0

	// AppMinor defines the minor version of this binary.
	AppMinor uint = 1

	// AppPatch defines the application patch for this binary.
	AppPatch uint = 0

	// AppPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	AppPreRelease = "alpha"
)

These constants define the application version and follow the semantic versioning 2.0.0 spec (http://semver.org/).

Variables

View Source
var (
	// Commit stores the current commit of this build, which includes the
	// most recent tag, the number of commits since that tag (if non-zero),
	// the commit hash, and a dirty marker. This should be set using the
	// -ldflags during compilation.
	Commit string

	// CommitHash stores the current commit hash of this build.
	CommitHash string

	// RawTags contains the raw set of build tags, separated by commas.
	RawTags string

	// GoVersion stores the go version that the executable was compiled
	// with.
	GoVersion string
)
View Source
var (
	// RequiredPermissions is a map of all taro RPC methods and their
	// required macaroon permissions to access tarod.
	//
	// TODO(roasbeef): re think these and go instead w/ the * approach?
	RequiredPermissions = map[string][]bakery.Op{
		"/tarorpc.Taro/StopDaemon": {{
			Entity: "daemon",
			Action: "write",
		}},
		"/tarorpc.Taro/DebugLevel": {{
			Entity: "daemon",
			Action: "write",
		}},
		"/tarorpc.Taro/MintAsset": {{
			Entity: "assets",
			Action: "write",
		}},
		"/tarorpc.Taro/ListAssets": {{
			Entity: "assets",
			Action: "read",
		}},
		"/tarorpc.Taro/ListBalances": {{
			Entity: "assets",
			Action: "read",
		}},
		"/tarorpc.Taro/ListTransfers": {{
			Entity: "assets",
			Action: "read",
		}},
		"/tarorpc.Taro/QueryAddrs": {{
			Entity: "addresses",
			Action: "read",
		}},
		"/tarorpc.Taro/NewAddr": {{
			Entity: "addresses",
			Action: "write",
		}},
		"/tarorpc.Taro/DecodeAddr": {{
			Entity: "addresses",
			Action: "read",
		}},
		"/tarorpc.Taro/AddrReceives": {{
			Entity: "addresses",
			Action: "read",
		}},
		"/tarorpc.Taro/VerifyProof": {{
			Entity: "proofs",
			Action: "read",
		}},
		"/tarorpc.Taro/ExportProof": {{
			Entity: "proofs",
			Action: "read",
		}},
		"/tarorpc.Taro/ImportProof": {{
			Entity: "proofs",
			Action: "write",
		}},
		"/tarorpc.Taro/SendAsset": {{
			Entity: "assets",
			Action: "write",
		}},
	}
)

Functions

func AddSubLogger

func AddSubLogger(root *build.RotatingLogWriter, subsystem string,
	interceptor signal.Interceptor, useLoggers ...func(btclog.Logger))

AddSubLogger is a helper method to conveniently create and register the logger of one or more sub systems.

func SetSubLogger

func SetSubLogger(root *build.RotatingLogWriter, subsystem string,
	logger btclog.Logger, useLoggers ...func(btclog.Logger))

SetSubLogger is a helper method to conveniently register the logger of a sub system.

func SetupLoggers

func SetupLoggers(root *build.RotatingLogWriter, interceptor signal.Interceptor)

SetupLoggers initializes all package-global logger variables.

func Tags

func Tags() []string

Tags returns the list of build tags that were compiled into the executable.

func Version

func Version() string

Version returns the application version as a properly formed string per the semantic versioning 2.0.0 spec (http://semver.org/).

Types

type Config

type Config struct {
	DebugLevel string

	// TODO(roasbeef): use the taro chain param wrapper here?
	ChainParams chaincfg.Params

	SignalInterceptor signal.Interceptor

	AssetMinter tarogarden.Planter

	AssetCustodian *tarogarden.Custodian

	AddrBook *address.Book

	ProofArchive proof.Archiver

	ChainPorter tarofreighter.Porter

	// LogWriter is the root logger that all of the daemon's subloggers are
	// hooked up to.
	LogWriter *build.RotatingLogWriter

	*RPCConfig

	*DatabaseConfig
}

Config is the main config of the Taro server.

type DatabaseConfig

type DatabaseConfig struct {
	RootKeyStore *tarodb.RootKeyStore

	MintingStore tarogarden.MintingStore

	AssetStore *tarodb.AssetStore

	TaroAddrBook *tarodb.TaroAddressBook
}

DatabaseConfig is the config that holds all the persistence related structs and interfaces needed for tarod to function.

type LndRpcChainBridge

type LndRpcChainBridge struct {
	// contains filtered or unexported fields
}

LndRpcChainBridge is an implementation of the tarogarden.ChainBridge interface backed by an active remote lnd node.

func NewLndRpcChainBridge

func NewLndRpcChainBridge(lnd *lndclient.LndServices) *LndRpcChainBridge

NewLndRpcChainBridge creates a new chain bridge from an active lnd services client.

func (*LndRpcChainBridge) CurrentHeight

func (l *LndRpcChainBridge) CurrentHeight(ctx context.Context) (uint32, error)

CurrentHeight return the current height of the main chain.

func (*LndRpcChainBridge) EstimateFee

func (l *LndRpcChainBridge) EstimateFee(ctx context.Context,
	confTarget uint32) (chainfee.SatPerKWeight, error)

EstimateFee returns a fee estimate for the confirmation target.

func (*LndRpcChainBridge) PublishTransaction

func (l *LndRpcChainBridge) PublishTransaction(ctx context.Context,
	tx *wire.MsgTx) error

PublishTransaction attempts to publish a new transaction to the network.

func (*LndRpcChainBridge) RegisterConfirmationsNtfn

func (l *LndRpcChainBridge) RegisterConfirmationsNtfn(ctx context.Context,
	txid *chainhash.Hash, pkScript []byte, numConfs, heightHint uint32,
	includeBlock bool) (*chainntnfs.ConfirmationEvent, chan error, error)

RegisterConfirmationsNtfn registers an intent to be notified once txid reaches numConfs confirmations.

type LndRpcGenSigner

type LndRpcGenSigner struct {
	// contains filtered or unexported fields
}

LndRpcGenSigner is an implementation of the asset.GenesisSigner interface backed by an active lnd node.

func NewLndRpcGenSigner

func NewLndRpcGenSigner(lnd *lndclient.LndServices) *LndRpcGenSigner

NewLndRpcGenSigner returns a new gen signer instance backed by the passed connection to a remote lnd node.

func (*LndRpcGenSigner) SignGenesis

func (l *LndRpcGenSigner) SignGenesis(keyDesc keychain.KeyDescriptor,
	assetGen asset.Genesis) (*btcec.PublicKey, *schnorr.Signature, error)

SignGenesis signs the passed Genesis description using the public key identified by the passed key descriptor. The final tweaked public key and the signature are returned.

type LndRpcKeyRing

type LndRpcKeyRing struct {
	// contains filtered or unexported fields
}

LndRpcKeyRing is an implementation of the keychain.KeyRing interface backed by an active remote lnd node.

func NewLndRpcKeyRing

func NewLndRpcKeyRing(lnd *lndclient.LndServices) *LndRpcKeyRing

NewLndRpcKeyRing creates a new instance of the LndRpcKeyRing based on the passed ln client.

func (*LndRpcKeyRing) DeriveKey

DeriveKey attempts to derive an arbitrary key specified by the passed KeyLocator. This may be used in several recovery scenarios, or when manually rotating something like our current default node key.

func (*LndRpcKeyRing) DeriveNextKey

func (l *LndRpcKeyRing) DeriveNextKey(ctx context.Context,
	keyFam keychain.KeyFamily) (keychain.KeyDescriptor, error)

DeriveNextKey attempts to derive the *next* key within the key family (account in BIP43) specified. This method should return the next external child within this branch.

func (*LndRpcKeyRing) DeriveNextTaroKey

func (l *LndRpcKeyRing) DeriveNextTaroKey(
	ctx context.Context) (keychain.KeyDescriptor, error)

DeriveNextTaroKey attempts to derive the *next* key within the Taro key family.

type LndRpcVirtualTxSigner

type LndRpcVirtualTxSigner struct {
	// contains filtered or unexported fields
}

LndRpcVirtualTxSigner is an implementation of the taroscript.Signer interface backed by an active lnd node.

func NewLndRpcVirtualTxSigner

func NewLndRpcVirtualTxSigner(lnd *lndclient.LndServices) *LndRpcVirtualTxSigner

NewLndRpcVirtualTxSigner returns a new tx signer instance backed by the passed connection to a remote lnd node.

func (*LndRpcVirtualTxSigner) SignVirtualTx

func (l *LndRpcVirtualTxSigner) SignVirtualTx(signDesc *lndclient.SignDescriptor,
	tx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature, error)

SignVirtualTx generates a signature according to the passed signing descriptor and virtual TX.

NOTE: We currently assume the signature requested is for the BIP 86 spending type, and that the passed key is the internal key.

type LndRpcWalletAnchor

type LndRpcWalletAnchor struct {
	// contains filtered or unexported fields
}

LndRpcWalletAnchor is an implementation of the tarogarden.WalletAnchor interfaced backed by an active remote lnd node.

func NewLndRpcWalletAnchor

func NewLndRpcWalletAnchor(lnd *lndclient.LndServices) *LndRpcWalletAnchor

NewLndRpcWalletAnchor returns a new wallet anchor instance using the passed lnd node.

func (*LndRpcWalletAnchor) FundPsbt

func (l *LndRpcWalletAnchor) FundPsbt(ctx context.Context, packet *psbt.Packet,
	minConfs uint32, feeRate chainfee.SatPerKWeight) (tarogarden.FundedPsbt,
	error)

FundPsbt attaches enough inputs to the target PSBT packet for it to be valid.

func (*LndRpcWalletAnchor) ImportTaprootOutput

func (l *LndRpcWalletAnchor) ImportTaprootOutput(ctx context.Context,
	pub *btcec.PublicKey) (btcutil.Address, error)

ImportTaprootOutput imports a new public key into the wallet, as a P2TR output.

func (*LndRpcWalletAnchor) ListTransactions

func (l *LndRpcWalletAnchor) ListTransactions(ctx context.Context, startHeight,
	endHeight int32, account string) ([]lndclient.Transaction, error)

ListTransactions returns all known transactions of the backing lnd node. It takes a start and end block height which can be used to limit the block range that we query over. These values can be left as zero to include all blocks. To include unconfirmed transactions in the query, endHeight must be set to -1.

func (*LndRpcWalletAnchor) ListUnspentImportScripts

func (l *LndRpcWalletAnchor) ListUnspentImportScripts(
	ctx context.Context) ([]*lnwallet.Utxo, error)

ListUnspentImportScripts lists all UTXOs of the imported Taproot scripts.

func (*LndRpcWalletAnchor) SignAndFinalizePsbt

func (l *LndRpcWalletAnchor) SignAndFinalizePsbt(ctx context.Context,
	pkt *psbt.Packet) (*psbt.Packet, error)

SignAndFinalizePsbt fully signs and finalizes the target PSBT packet.

func (*LndRpcWalletAnchor) SignPsbt

func (l *LndRpcWalletAnchor) SignPsbt(ctx context.Context,
	packet *psbt.Packet) (*psbt.Packet, error)

SignPsbt...

func (*LndRpcWalletAnchor) SubscribeTransactions

func (l *LndRpcWalletAnchor) SubscribeTransactions(
	ctx context.Context) (<-chan lndclient.Transaction, <-chan error,
	error)

SubscribeTransactions creates a uni-directional stream from the server to the client in which any newly discovered transactions relevant to the wallet are sent over.

func (*LndRpcWalletAnchor) UnlockInput

func (l *LndRpcWalletAnchor) UnlockInput(ctx context.Context) error

UnlockInput unlocks the set of target inputs after a batch is abandoned.

type RPCConfig

type RPCConfig struct {
	LisCfg *lnd.ListenerCfg

	RPCListeners []net.Addr

	RESTListeners []net.Addr

	GrpcServerOpts []grpc.ServerOption

	RestDialOpts []grpc.DialOption

	RestListenFunc func(net.Addr) (net.Listener, error)

	WSPingInterval time.Duration

	WSPongWait time.Duration

	RestCORS []string

	NoMacaroons bool

	MacaroonPath string
}

RPCConfig is a sub-config of the main server that packages up everything needed to start the RPC server.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the main daemon construct for the Taro server. It handles spinning up the RPC sever, the database, and any other components that the taro server needs to function.

func NewServer

func NewServer(cfg *Config) (*Server, error)

NewServer creates a new server given the passed config.

func (*Server) RunUntilShutdown

func (s *Server) RunUntilShutdown(mainErrChan <-chan error) error

RunUntilShutdown runs the main Taro server loop until a signal is received to shut down the process.

func (*Server) Stop

func (s *Server) Stop() error

Stop signals that the main taro server should attempt a graceful shutdown.

type ValidatorV0

type ValidatorV0 struct{}

ValidatorV0 is an implementation of the taroscript.TxValidator interface that supports Taro script version 0.

func (*ValidatorV0) Execute

func (v *ValidatorV0) Execute(newAsset *asset.Asset,
	splitAsset *commitment.SplitAsset,
	prevAssets commitment.InputSet) error

Execute creates and runs an instance of the Taro script V0 VM.

Directories

Path Synopsis
cmd
internal
Package tarorpc is a reverse proxy.
Package tarorpc is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL