tredd

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jan 27, 2019 License: MIT Imports: 17 Imported by: 0

README

TREDD - Trustless escrow for digital data

This is Tredd, a software library that allows a buyer and a seller of some information to exchange payment for data securely.

It relies on the TxVM blockchain and includes a demonstration client and server (in cmd/tredd).

A buyer sends a request for some content to a seller. The seller responds with an encrypted copy of the content. The seller sends a partial blockchain transaction to the seller, containing payment for the content. The seller completes the partial transaction and publishes it to the blockchain. The completed transaction reveals the decryption key, which the buyer uses to decrypt the content. The buyer has a way to claim a refund if the key fails to produce the promised content.

For more information, see this detailed explanation of Tredd’s design and operation.

For the motivation behind Tredd, see Why Tredd.

For step-by-step instructions for running the Tredd server and client, see Trying Tredd.

Documentation

Overview

Package tredd implements trustless escrow for digital data, as described at https://docs.google.com/document/d/1eC36V8fX9AVXJDNx1qiCksAj03C9DOp9YCWzIC2wKJE/edit?usp=sharing.

Index

Constants

View Source
const ChunkSize = 8192

ChunkSize is the size of a chunk of Tredd data.

Variables

This section is empty.

Functions

func ClaimPayment

func ClaimPayment(r *Redeem) ([]byte, error)

ClaimPayment constructs a seller-claims-payment transaction, rehydrating and invoking a Tredd contract from the utxo state (identified by the information in r).

func ClaimRefund

func ClaimRefund(r *Redeem, index int64, cipherChunk []byte, clearHash []byte, cipherProof, clearProof merkle.Proof) ([]byte, error)

ClaimRefund constructs a buyer-claims-refund transaction, rehydrating a Tredd contract from the utxo state (identified by the information in r) and calling it with the necessary proofs and other information.

func Crypt

func Crypt(key [32]byte, chunk []byte, index uint64)

func Decrypt

func Decrypt(w io.Writer, clearHashes, cipherChunks ChunkStore, key [32]byte) error

Decrypt decrypts the chunks in cipherChunks by xoring with hashes derived from key. It writes the concatenated cleartext chunks to w. Along the way, it compares each cleartext chunk's hash to the corresponding value in clearHashes. If it finds a mismatch, it returns a BadClearHashError.

func Get

func Get(r io.Reader, clearRoot [32]byte, clearHashes, cipherChunks ChunkStore) ([]byte, error)

Get parses a stream of interleaved <clearhash><cipherchunk> pairs, placing them in their respective ChunkStores. Along the way it compares the clear hashes' Merkle root hash to the expected value in clearRoot. If it finds a mismatch it returns errBadClearRoot. If there is no error, the Merkle root hash of the cipher chunks is returned. Both Merkle root hashes are computed from values prepended with the chunk index number.

func ProposePayment

func ProposePayment(
	ctx context.Context,
	buyer ed25519.PublicKey,
	amount int64,
	assetID bc.Hash,
	clearRoot, cipherRoot [32]byte,
	now, revealDeadline, refundDeadline time.Time,
	reserver Reserver,
	signer Signer,
) ([]byte, error)

ProposePayment constructs a partial transaction in which the buyer commits funds to the Tredd contract.

func RevealKey

func RevealKey(
	ctx context.Context,
	paymentProposal []byte,
	seller ed25519.PublicKey,
	key [32]byte,
	amount int64,
	assetID bc.Hash,
	reserver Reserver,
	signer Signer,
	wantClearRoot, wantCipherRoot [32]byte,
	now, wantRevealDeadline, wantRefundDeadline time.Time,
) ([]byte, error)

RevealKey completes the partial transaction in paymentProposal (which came from ProposePayment). The Tredd contract is on the contract stack. The arg stack is empty.

func Serve

func Serve(w io.Writer, r io.Reader, key [32]byte) ([]byte, error)

Serve produces a stream of interleaved <clearhash><cipherchunk> pairs from the content in r. It writes the stream to w, encrypting the chunks by xoring with hashes derived from key. The return value is the Merkle root hash of the cipher chunks, each prepended with its chunk index. TODO: Cleartext chunks and their hashes can be precomputed and supplied as ChunkStores.

Types

type BadClearHashError

type BadClearHashError struct {
	// Index is the index of the chunk and of the hash within their respective ChunkStores.
	Index uint64
}

BadClearHashError gives the index of a cleartext chunk whose hash doesn't have the expected value.

func (BadClearHashError) Error

func (e BadClearHashError) Error() string

type ChunkStore

type ChunkStore interface {
	// Add adds a chunk to the end of the ChunkStore.
	Add([]byte) error

	// Get gets the chunk with the given index (0-based).
	Get(uint64) ([]byte, error)

	// Len tells the number of chunks in the store.
	Len() (int64, error)
}

ChunkStore stores and retrieves data in chunks. The chunk size need not be ChunkSize.

type ParseResult

type ParseResult struct {
	// Amount is the amount of the buyer's payment (not including the seller's collateral).
	Amount  int64
	AssetID []byte

	// Anchor1 is the anchor in the Value tuple of the buyer's payment.
	Anchor1 []byte

	// Anchor2 is the anchor in the Value tuple of the buyer's payment after merging with the seller's collateral.
	Anchor2        []byte
	ClearRoot      []byte
	CipherRoot     []byte
	RevealDeadline time.Time
	RefundDeadline time.Time
	Buyer          ed25519.PublicKey
	Seller         ed25519.PublicKey
	Key            []byte

	// OutputID is the id of the Tredd contract UTXO while awaiting redemption.
	OutputID []byte
}

ParseResult holds the values parsed from the log of a transaction that invokes the propose-payment phase of a Tredd contract. If the transaction is complete (i.e., the seller has added the "reveal-key" call), all of the fields will be filled in. If the transaction is partial, some fields will be uninitialized.

func ParseLog

func ParseLog(prog []byte) *ParseResult

ParseLog parses the log of a (possibly partial) transaction program. If the log shows a call to an instance of the Tredd contract, ParseLog returns a ParseResult containing information extracted from the log. Otherwise it returns nil.

type Redeem

type Redeem struct {
	RefundDeadline time.Time
	Buyer, Seller  ed25519.PublicKey

	// Amount is the sum of the payment and the collateral (i.e., the buyer's payment times 2).
	Amount  int64
	AssetID bc.Hash

	// Anchor2 is the anchor of the Value tuple holding the payment+collateral.
	Anchor2               [32]byte
	CipherRoot, ClearRoot [32]byte
	Key                   [32]byte
}

Redeem holds the values needed to redeem a Tredd contract (whether by the seller claiming payment or the buyer claiming a refund).

type Reservation

type Reservation interface {
	UTXOs(context.Context) ([]UTXO, error)
	Change(context.Context) (int64, error)
	Cancel(context.Context) error
}

Reservation is the result of reserving some UTXOs with a Reserver.

type Reserver

type Reserver interface {
	Reserve(ctx context.Context, amount int64, assetID bc.Hash, now, exp time.Time) (Reservation, error)
}

Reserver can reserve UTXOs for spending before a given expiration time. A UTXO, once reserved, will not appear in another Reservation until/unless the first reservation expires or is canceled.

type Signer

type Signer func([]byte) ([]byte, error)

Signer is the type of a function that produces a signature of a given message.

type UTXO

type UTXO interface {
	Amount() int64
	AssetID() bc.Hash
	Anchor() []byte
}

UTXO is the type of an unspent output in the blockchain's UTXO set.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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