func (formal Formal) MarshalJSON() ([]byte, error) {
	return json.Marshal(formal)
}
MarshalJSON implements the json.Marshaler interface for the Formal type.
package v0
import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"golang.org/x/crypto/sha3"
)
type Shard [32]byte
func (shard Shard) String() string {
	return base64.RawStdEncoding.EncodeToString(shard[:])
}
var (
	IntrinsicDefault = Shard(sha3.Sum256([]byte{}))
	IntrinsicBtc = Shard(sha3.Sum256([]byte("Btc")))
	IntrinsicZec = Shard(sha3.Sum256([]byte("Zec")))
	IntrinsicBch = Shard(sha3.Sum256([]byte("Bch")))
	IntrinsicEth = Shard(sha3.Sum256([]byte("Eth")))
)
func ValidateAddress(addr Address) error {
	switch addr {
	case IntrinsicBTC0Btc2Eth.Address,
		IntrinsicZEC0Zec2Eth.Address,
		IntrinsicBCH0Bch2Eth.Address,
		IntrinsicBTC0Eth2Btc.Address,
		IntrinsicZEC0Eth2Zec.Address,
		IntrinsicBCH0Eth2Bch.Address:
		return nil
	default:
		return fmt.Errorf("invalid v0 contract address")
	}
}
func IsShiftIn(addr Address) bool {
	switch addr {
	case IntrinsicBTC0Btc2Eth.Address, IntrinsicZEC0Zec2Eth.Address, IntrinsicBCH0Bch2Eth.Address:
		return true
	case IntrinsicBTC0Eth2Btc.Address, IntrinsicZEC0Eth2Zec.Address, IntrinsicBCH0Eth2Bch.Address:
		return false
	default:
		panic("unknown shift")
	}
}
var IntrinsicBTC0Btc2Eth = Contract{
	Address: "BTC0Btc2Eth",
	In: Formals{
		{"p", ExtTypeEthCompatPayload},      
		{"token", ExtTypeEthCompatAddress},  
		{"to", ExtTypeEthCompatAddress},     
		{"n", TypeB32},                      
		{"utxo", ExtTypeBtcCompatUTXO},      
	},
	Autogen: Formals{
		{"ghash", TypeB32},              
		{"nhash", TypeB32},              
		{"phash", TypeB32},              
		{"sighash", TypeB32},            
		{"amount", TypeU256},            
		{"utxo", ExtTypeBtcCompatUTXO},  
	},
	Out: Formals{
		{"r", TypeB32},  
		{"s", TypeB32},  
		{"v", TypeU8},   
	},
}
var IntrinsicBTC0Eth2Btc = Contract{
	Address: "BTC0Eth2Btc",
	In: Formals{
		{"ref", TypeU64},  
	},
	Out: Formals{
		{"txhash", TypeB},  
	},
}
var IntrinsicBCH0Bch2Eth = Contract{
	Address: "BCH0Bch2Eth",
	In: Formals{
		{"p", ExtTypeEthCompatPayload},      
		{"token", ExtTypeEthCompatAddress},  
		{"to", ExtTypeEthCompatAddress},     
		{"n", TypeB32},                      
		{"utxo", ExtTypeBtcCompatUTXO},      
	},
	Autogen: Formals{
		{"ghash", TypeB32},              
		{"nhash", TypeB32},              
		{"phash", TypeB32},              
		{"sighash", TypeB32},            
		{"amount", TypeU256},            
		{"utxo", ExtTypeBtcCompatUTXO},  
	},
	Out: Formals{
		{"r", TypeB32},  
		{"s", TypeB32},  
		{"v", TypeU8},   
	},
}
var IntrinsicBCH0Eth2Bch = Contract{
	Address: "BCH0Eth2Bch",
	In: Formals{
		{"ref", TypeU64},  
	},
	Out: Formals{
		{"txhash", TypeB},  
	},
}
var IntrinsicZEC0Zec2Eth = Contract{
	Address: "ZEC0Zec2Eth",
	In: Formals{
		{"p", ExtTypeEthCompatPayload},      
		{"token", ExtTypeEthCompatAddress},  
		{"to", ExtTypeEthCompatAddress},     
		{"n", TypeB32},                      
		{"utxo", ExtTypeBtcCompatUTXO},      
	},
	Autogen: Formals{
		{"ghash", TypeB32},              
		{"nhash", TypeB32},              
		{"phash", TypeB32},              
		{"sighash", TypeB32},            
		{"amount", TypeU256},            
		{"utxo", ExtTypeBtcCompatUTXO},  
	},
	Out: Formals{
		{"r", TypeB32},  
		{"s", TypeB32},  
		{"v", TypeU8},   
	},
}
var IntrinsicZEC0Eth2Zec = Contract{
	Address: "ZEC0Eth2Zec",
	In: Formals{
		{"ref", TypeU64},  
	},
	Out: Formals{
		{"txhash", TypeB},  
	},
}
var Intrinsics = map[Address]Contract{
	IntrinsicBTC0Btc2Eth.Address: IntrinsicBTC0Btc2Eth,
	IntrinsicBTC0Eth2Btc.Address: IntrinsicBTC0Eth2Btc,
	IntrinsicZEC0Zec2Eth.Address: IntrinsicZEC0Zec2Eth,
	IntrinsicZEC0Eth2Zec.Address: IntrinsicZEC0Eth2Zec,
	IntrinsicBCH0Bch2Eth.Address: IntrinsicBCH0Bch2Eth,
	IntrinsicBCH0Eth2Bch.Address: IntrinsicBCH0Eth2Bch,
}
type Contracts []Contract
type Contract struct {
	Address Address `json:"address"`
	In      Formals `json:"in"`
	Autogen Formals `json:"autogen"`
	Out     Formals `json:"out"`
}
type Formals []Formal
type Formal struct {
	Name string `json:"name"`
	Type Type   `json:"type"`
}