bitcoind

package module
v0.0.0-...-9dedf42 Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2018 License: MIT Imports: 10 Imported by: 1

README

bitcoind

A Golang client library wrapping the bitcoind JSON RPC API

Installation

$ go get https://github.com/Toorop/go-bitcoind

Usage

package main

import (
	"github.com/toorop/go-bitcoind"
	"log"
)

const (
	SERVER_HOST        = "You server host"
	SERVER_PORT        = port (int)
	USER               = "user"
	PASSWD             = "passwd"
	USESSL             = false
	WALLET_PASSPHRASE  = "WalletPassphrase"
)

func main() {
	bc, err := bitcoind.New(SERVER_HOST, SERVER_PORT, USER, PASSWD, USESSL)
	if err != nil {
		log.Fatalln(err)
	}

	//walletpassphrase
	err = bc.WalletPassphrase(WALLET_PASSPHRASE, 3600)
	log.Println(err)

	// backupwallet
	err = bc.BackupWallet("/tmp/wallet.dat")
	log.Println(err)


	// dumpprivkey
	privKey, err := bc.DumpPrivKey("1KU5DX7jKECLxh1nYhmQ7CahY7GMNMVLP3")
	log.Println(err, privKey)

}

Mores examples in example.go (in examples folder)

Documentation

Click on the button below to access the full documentation:

GoDoc

Unit tests

Build Status

More than 100 unit tests are made.

To run tests:

$ go get github.com/onsi/ginkgo/ginkgo
$ go get github.com/onsi/gomega
$ ginkgo

Running Suite: Bitcoind Suite	
=============================
Random Seed: 1401120770
Will run 112 of 112 specs

•••••••••••••••••••••••••••••••••••
Ran 112 of 112 Specs in 0.001 seconds
SUCCESS! -- 112 Passed | 0 Failed | 0 Pending | 0 Skipped PASS

Ginkgo ran in 10.856335553s
Test Suite Passed

Todo

  • GetBlockTemplate
  • sendrawtransaction
  • signrawtransaction
  • submitblock
Note on SSL support

Note on ssl support : bitcoind library doesn't verify the server's certificate chain. That means that it accepts any certificate presented by the server and any host name in that certificate. In this mode, TLS is susceptible to man-in-the-middle attacks.

Donation

Donation QR

1HgpsmxV52eAjDcoNpVGpYEhGfgN7mM1JB

Documentation

Overview

Package Bitcoind is client librari for bitcoind JSON RPC API

Index

Constants

View Source
const (
	// VERSION represents bicoind package version
	VERSION = 0.1
	// DEFAULT_RPCCLIENT_TIMEOUT represent http timeout for rcp client
	RPCCLIENT_TIMEOUT = 30
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Bitcoind

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

A Bitcoind represents a Bitcoind client

func New

func New(host string, port int, user, passwd string, useSSL bool) (*Bitcoind, error)

New return a new bitcoind

func (*Bitcoind) BackupWallet

func (b *Bitcoind) BackupWallet(destination string) error

BackupWallet Safely copies wallet.dat to destination, which can be a directory or a path with filename on the remote server

func (*Bitcoind) DumpPrivKey

func (b *Bitcoind) DumpPrivKey(address string) (privKey string, err error)

DumpPrivKey return private key as string associated to public <address>

func (*Bitcoind) EncryptWallet

func (b *Bitcoind) EncryptWallet(passphrase string) error

EncryptWallet encrypts the wallet with <passphrase>.

func (*Bitcoind) GetAccount

func (b *Bitcoind) GetAccount(address string) (account string, err error)

GetAccount returns the account associated with the given address.

func (*Bitcoind) GetAccountAddress

func (b *Bitcoind) GetAccountAddress(account string) (address string, err error)

GetAccountAddress Returns the current bitcoin address for receiving payments to this account. If account does not exist, it will be created along with an associated new address that will be returned.

func (*Bitcoind) GetAddressesByAccount

func (b *Bitcoind) GetAddressesByAccount(account string) (addresses []string, err error)

GetAddressesByAccount return addresses associated with account <account>

func (*Bitcoind) GetBalance

func (b *Bitcoind) GetBalance(account string, minconf uint64) (balance float64, err error)

GetBalance return the balance of the server or of a specific account If [account] is "", returns the server's total available balance. If [account] is specified, returns the balance in the account

func (*Bitcoind) GetBestBlockhash

func (b *Bitcoind) GetBestBlockhash() (bestBlockHash string, err error)

GetBestBlockhash returns the hash of the best (tip) block in the longest block chain.

func (*Bitcoind) GetBlock

func (b *Bitcoind) GetBlock(blockHash string) (block Block, err error)

GetBlock returns information about the block with the given hash.

func (*Bitcoind) GetBlockCount

func (b *Bitcoind) GetBlockCount() (count uint64, err error)

GetBlockCount returns the number of blocks in the longest block chain.

func (*Bitcoind) GetBlockHash

func (b *Bitcoind) GetBlockHash(index uint64) (hash string, err error)

GetBlockHash returns hash of block in best-block-chain at <index>

func (*Bitcoind) GetBlockTemplate

func (b *Bitcoind) GetBlockTemplate(capabilities []string, mode string) (template string, err error)

TODO a finir GetBlockTemplate Returns data needed to construct a block to work on. See BIP_0022 for more info on params.

func (*Bitcoind) GetBlockchainInfo

func (b *Bitcoind) GetBlockchainInfo() (i BlockchainInfo, err error)

GetInfo return result of "getinfo" command (Amazing !)

func (*Bitcoind) GetConnectionCount

func (b *Bitcoind) GetConnectionCount() (count uint64, err error)

GetConnectionCount returns the number of connections to other nodes.

func (*Bitcoind) GetDifficulty

func (b *Bitcoind) GetDifficulty() (difficulty float64, err error)

GetDifficulty returns the proof-of-work difficulty as a multiple of the minimum difficulty.

func (*Bitcoind) GetGenerate

func (b *Bitcoind) GetGenerate() (generate bool, err error)

GetGenerate returns true or false whether bitcoind is currently generating hashes

func (*Bitcoind) GetHashesPerSec

func (b *Bitcoind) GetHashesPerSec() (hashpersec float64, err error)

GetHashesPerSec returns a recent hashes per second performance measurement while generating.

func (*Bitcoind) GetInfo

func (b *Bitcoind) GetInfo() (i Info, err error)

GetInfo return result of "getinfo" command (Amazing !)

func (*Bitcoind) GetMiningInfo

func (b *Bitcoind) GetMiningInfo() (miningInfo MiningInfo, err error)

GetMiningInfo returns an object containing mining-related information

func (*Bitcoind) GetNewAddress

func (b *Bitcoind) GetNewAddress(account ...string) (addr string, err error)

GetNewAddress return a new address for account [account].

func (*Bitcoind) GetPeerInfo

func (b *Bitcoind) GetPeerInfo() (peerInfo []Peer, err error)

GetPeerInfo returns data about each connected node

func (*Bitcoind) GetRawChangeAddress

func (b *Bitcoind) GetRawChangeAddress(account ...string) (rawAddress string, err error)

GetRawChangeAddress Returns a new Bitcoin address, for receiving change. This is for use with raw transactions, NOT normal use.

func (*Bitcoind) GetRawMempool

func (b *Bitcoind) GetRawMempool() (txId []string, err error)

GetRawMempool returns all transaction ids in memory pool

func (*Bitcoind) GetRawTransaction

func (b *Bitcoind) GetRawTransaction(txId string, verbose bool) (rawTx interface{}, err error)

GetRawTransaction returns raw transaction representation for given transaction id.

func (*Bitcoind) GetReceivedByAccount

func (b *Bitcoind) GetReceivedByAccount(account string, minconf uint32) (amount float64, err error)

GetReceivedByAccount Returns the total amount received by addresses with [account] in transactions with at least [minconf] confirmations. If [account] is set to all return will include all transactions to all accounts

func (*Bitcoind) GetReceivedByAddress

func (b *Bitcoind) GetReceivedByAddress(address string, minconf uint32) (amount float64, err error)

Returns the amount received by <address> in transactions with at least [minconf] confirmations. It correctly handles the case where someone has sent to the address in multiple transactions. Keep in mind that addresses are only ever used for receiving transactions. Works only for addresses in the local wallet, external addresses will always show 0.

func (*Bitcoind) GetTransaction

func (b *Bitcoind) GetTransaction(txid string) (transaction Transaction, err error)

GetTransaction returns a Bitcoind.Transation struct about the given transaction

func (*Bitcoind) GetTxOut

func (b *Bitcoind) GetTxOut(txid string, n uint32, includeMempool bool) (transactionOut UTransactionOut, err error)

GetTxOut returns details about an unspent transaction output (UTXO)

func (*Bitcoind) GetTxOutsetInfo

func (b *Bitcoind) GetTxOutsetInfo() (txOutSet TransactionOutSet, err error)

GetTxOutsetInfo returns statistics about the unspent transaction output (UTXO) set

func (*Bitcoind) GetWork

func (b *Bitcoind) GetWork(data ...string) (response interface{}, err error)

GetWork If [data] is not specified, returns formatted hash data to work on If [data] is specified, tries to solve the block and returns true if it was successful.

func (*Bitcoind) ImportPrivKey

func (b *Bitcoind) ImportPrivKey(privKey, label string, rescan bool) error

ImportPrivKey Adds a private key (as returned by dumpprivkey) to your wallet. This may take a while, as a rescan is done, looking for existing transactions. Optional [rescan] parameter added in 0.8.0. Note: There's no need to import public key, as in ECDSA (unlike RSA) this can be computed from private key.

func (*Bitcoind) KeyPoolRefill

func (b *Bitcoind) KeyPoolRefill() error

KeyPoolRefill fills the keypool, requires wallet passphrase to be set.

func (*Bitcoind) ListAccounts

func (b *Bitcoind) ListAccounts(minconf int32) (accounts map[string]float64, err error)

ListAccounts returns Object that has account names as keys, account balances as values.

func (*Bitcoind) ListAddressGroupings

func (b *Bitcoind) ListAddressGroupings() (list []ListAddressResult, err error)

ListAddressGroupings returns all addresses in the wallet and info used for coincontrol.

func (*Bitcoind) ListLockUnspent

func (b *Bitcoind) ListLockUnspent() (unspendableOutputs []UnspendableOutput, err error)

ListLockUnspent returns list of temporarily unspendable outputs

func (*Bitcoind) ListReceivedByAccount

func (b *Bitcoind) ListReceivedByAccount(minConf uint32, includeEmpty bool) (list []ReceivedByAccount, err error)

ListReceivedByAccount Returns an slice of AccountRecieved:

func (*Bitcoind) ListReceivedByAddress

func (b *Bitcoind) ListReceivedByAddress(minConf uint32, includeEmpty bool) (list []ReceivedByAddress, err error)

ListReceivedByAccount Returns an slice of AccountRecieved:

func (*Bitcoind) ListSinceBlock

func (b *Bitcoind) ListSinceBlock(blockHash string, targetConfirmations uint32) (transaction []Transaction, err error)

ListSinceBlock

func (*Bitcoind) ListTransactions

func (b *Bitcoind) ListTransactions(account string, count, from uint32) (transaction []Transaction, err error)

ListTransactions returns up to [count] most recent transactions skipping the first [from] transactions for account [account]. If [account] not provided it'll return recent transactions from all accounts.

func (*Bitcoind) ListUnspent

func (b *Bitcoind) ListUnspent(minconf, maxconf uint32) (transactions []Transaction, err error)

ListUnspent returns array of unspent transaction inputs in the wallet.

func (*Bitcoind) LockUnspent

func (b *Bitcoind) LockUnspent(lock bool, outputs []UnspendableOutput) (success bool, err error)

LockUnspent updates(lock/unlock) list of temporarily unspendable outputs

func (*Bitcoind) Move

func (b *Bitcoind) Move(formAccount, toAccount string, amount float64, minconf uint32, comment string) (success bool, err error)

Move from one account in your wallet to another

func (*Bitcoind) SendFrom

func (b *Bitcoind) SendFrom(fromAccount, toAddress string, amount float64, minconf uint32, comment, commentTo string) (txID string, err error)

SendFrom send amount from fromAccount to toAddress

amount is a real and is rounded to 8 decimal places.
Will send the given amount to the given address, ensuring the account has a valid balance using [minconf] confirmations.

func (*Bitcoind) SendMany

func (b *Bitcoind) SendMany(fromAccount string, amounts map[string]float64, minconf uint32, comment string) (txID string, err error)

SenMany send multiple times

func (*Bitcoind) SendToAddress

func (b *Bitcoind) SendToAddress(toAddress string, amount float64, comment, commentTo string) (txID string, err error)

SendToAddress send an amount to a given address

func (*Bitcoind) SetAccount

func (b *Bitcoind) SetAccount(address, account string) error

SetAccount sets the account associated with the given address

func (*Bitcoind) SetGenerate

func (b *Bitcoind) SetGenerate(generate bool, genProcLimit int32) error

SetGenerate turns generation on or off. Generation is limited to [genproclimit] processors, -1 is unlimited.

func (*Bitcoind) SetTxFee

func (b *Bitcoind) SetTxFee(amount float64) error

SetTxFee set the transaction fee per kB

func (*Bitcoind) SignMessage

func (b *Bitcoind) SignMessage(address, message string) (sig string, err error)

SignMessage sign a message with the private key of an address

func (*Bitcoind) Stop

func (b *Bitcoind) Stop() error

Stop stop bitcoin server.

func (*Bitcoind) ValidateAddress

func (b *Bitcoind) ValidateAddress(address string) (va ValidateAddressResponse, err error)

ValidateAddress return information about <bitcoinaddress>.

func (*Bitcoind) VerifyMessage

func (b *Bitcoind) VerifyMessage(address, sign, message string) (success bool, err error)

Verifymessage Verify a signed message.

func (*Bitcoind) WalletLock

func (b *Bitcoind) WalletLock() error

WalletLock Removes the wallet encryption key from memory, locking the wallet. After calling this method, you will need to call walletpassphrase again before being able to call any methods which require the wallet to be unlocked.

func (*Bitcoind) WalletPassphrase

func (b *Bitcoind) WalletPassphrase(passPhrase string, timeout uint64) error

walletPassphrase stores the wallet decryption key in memory for <timeout> seconds.

func (*Bitcoind) WalletPassphraseChange

func (b *Bitcoind) WalletPassphraseChange(oldPassphrase, newPassprhase string) error

type Block

type Block struct {
	// The block hash
	Hash string `json:"hash"`

	// The number of confirmations
	Confirmations uint64 `json:"confirmations"`

	// The block size
	Size uint64 `json:"size"`

	// The block height or index
	Height uint64 `json:"height"`

	// The block version
	Version uint32 `json:"version"`

	// The merkle root
	Merkleroot string `json:"merkleroot"`

	// Slice on transaction ids
	Tx []string `json:"tx"`

	// The block time in seconds since epoch (Jan 1 1970 GMT)
	Time int64 `json:"time"`

	// The nonce
	Nonce uint64 `json:"nonce"`

	// The bits
	Bits string `json:"bits"`

	// The difficulty
	Difficulty float64 `json:"difficulty"`

	// Total amount of work in active chain, in hexadecimal
	Chainwork string `json:"chainwork,omitempty"`

	// The hash of the previous block
	Previousblockhash string `json:"previousblockhash"`

	// The hash of the next block
	Nextblockhash string `json:"nextblockhash"`
}

Represents a block

type BlockchainInfo

type BlockchainInfo struct {
	Blocks               float64 `json:"blocks"`
	Initialblockdownload bool    `json:"initialblockdownload"`
	Mediantime           int64   `json:"mediantime"`
}

type Info

type Info struct {
	// The server version
	Version uint32 `json:"version"`

	// The protocol version
	Protocolversion uint32 `json:"protocolversion"`

	// The wallet version
	Walletversion uint32 `json:"walletversion"`

	// The total bitcoin balance of the wallet
	Balance float64 `json:"balance"`

	// The current number of blocks processed in the server
	Blocks uint32 `json:"blocks"`

	// The time offset
	Timeoffset int32 `json:"timeoffset"`

	// The number of connections
	Connections uint32 `json:"connections"`

	// Tthe proxy used by the server
	Proxy string `json:"proxy,omitempty"`

	// Tthe current difficulty
	Difficulty float64 `json:"difficulty"`

	// If the server is using testnet or not
	Testnet bool `json:"testnet"`

	// The timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool
	Keypoololdest uint64 `json:"keypoololdest"`

	// How many new keys are pre-generated
	KeypoolSize uint32 `json:"keypoolsize,omitempty"`

	// The timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked
	UnlockedUntil int64 `json:"unlocked_until,omitempty"`

	// the transaction fee set in btc/kb
	Paytxfee float64 `json:"paytxfee"`

	// Minimum relay fee for non-free transactions in btc/kb
	Relayfee float64 `json:"relayfee"`

	//  Any error messages
	Errors string `json:"errors"`
}

An Info represent a response to getmininginfo

type ListAddressResult

type ListAddressResult struct {
	Address string
	Amount  float64
	Account string
}

ListAddressResult represents a result composing ListAddressGroupings slice reply

type MiningInfo

type MiningInfo struct {
	// The current block
	Blocks uint64 `json:"blocks"`

	// The last block size
	CurrentBlocksize uint64 `json:"currentblocksize"`

	// The last block transaction
	CurrentBlockTx uint64 `json:"currentblocktx"`

	// The current difficulty
	Difficulty float64 `json:"difficulty"`

	// Current errors
	Errors string `json:"errors"`

	// The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)
	GenProcLimit int32 `json:"genproclimit"`

	// The size of the mem pool
	PooledtTx uint64 `json:"pooledtx"`

	// If using testnet or not
	Testnet bool `json:"testnet"`

	// If the generation is on or off (see getgenerate or setgenerate calls)
	Generate bool `json:"generate"`

	// The network hashrate
	NetworkHashps uint64 `json:"networkhashps"`

	// Node hashrate
	HashesPersec uint64 `json:"hashespersec"`
}

A MiningInfo represents a mininginfo response

type Peer

type Peer struct {
	// The ip address and port of the peer
	Addr string `json:"addr"`

	// Local address
	Addrlocal string `json:"addrlocal"`

	// The services
	Services string `json:"services"`

	// The time in seconds since epoch (Jan 1 1970 GMT) of the last send
	Lastsend uint64 `json:"lastsend"`

	// The time in seconds since epoch (Jan 1 1970 GMT) of the last receive
	Lastrecv uint64 `json:"lastrecv"`

	// The total bytes sent
	Bytessent uint64 `json:"bytessent"`

	// The total bytes received
	Bytesrecv uint64 `json:"bytesrecv"`

	// The connection time in seconds since epoch (Jan 1 1970 GMT)
	Conntime uint64 `json:"conntime"`

	// Ping time
	Pingtime float64 `json:"pingtime"`

	// Ping Wait
	Pingwait float64 `json:"pingwait"`

	// The peer version, such as 7001
	Version uint32 `json:"version"`

	// The string version
	Subver string `json:"subver"`

	// Inbound (true) or Outbound (false)
	Inbound bool `json:"inbound"`

	//  The starting height (block) of the peer
	Startingheight int32 `json:"startingheight"`

	// The ban score (stats.nMisbehavior)
	Banscore int32 `json:"banscore"`

	// If sync node
	Syncnode bool `json:"syncnode"`
}

type RawTransaction

type RawTransaction struct {
	Hex           string `json:"hex"`
	Txid          string `json:"txid"`
	Version       uint32 `json:"version"`
	LockTime      uint32 `json:"locktime"`
	Vin           []Vin  `json:"vin"`
	Vout          []Vout `json:"vout"`
	BlockHash     string `json:"blockhash,omitempty"`
	Confirmations uint64 `json:"confirmations,omitempty"`
	Time          int64  `json:"time,omitempty"`
	Blocktime     int64  `json:"blocktime,omitempty"`
}

RawTx represents a raw transaction

type ReceivedByAccount

type ReceivedByAccount struct {
	// the account of the receiving addresses
	Account string
	// total amount received by addresses with this account
	Amount float64
	// number of confirmations of the most recent transaction included
	Confirmations uint32
}

ReceivedByAccount represents how much coin a account have recieved

type ReceivedByAddress

type ReceivedByAddress struct {
	//  receiving address
	Address string
	// The corresponding account
	Account string
	// total amount received by addresses with this account
	Amount float64
	// number of confirmations of the most recent transaction included
	Confirmations uint32
	// Tansactions ID
	TxIds []string
}

ReceivedByAddress represents how much coin a account have recieved

type ScriptPubKey

type ScriptPubKey struct {
	Asm       string   `json:"asm"`
	Hex       string   `json:"hex"`
	ReqSigs   int      `json:"reqSigs,omitempty"`
	Type      string   `json:"type"`
	Addresses []string `json:"addresses,omitempty"`
}

type ScriptSig

type ScriptSig struct {
	Asm string `json:"asm"`
	Hex string `json:"hex"`
}

A ScriptSig represents a scriptsyg

type Transaction

type Transaction struct {
	Amount          float64              `json:"amount"`
	Account         string               `json:"account,omitempty"`
	Address         string               `json:"address,omitempty"`
	Category        string               `json:"category,omitempty"`
	Fee             float64              `json:"fee,omitempty"`
	Confirmations   int64                `json:"confirmations"`
	BlockHash       string               `json:"blockhash"`
	BlockIndex      int64                `json:"blockindex"`
	BlockTime       int64                `json:"blocktime"`
	TxID            string               `json:"txid"`
	WalletConflicts []string             `json:"walletconflicts"`
	Time            int64                `json:"time"`
	TimeReceived    int64                `json:"timereceived"`
	Details         []TransactionDetails `json:"details,omitempty"`
	Hex             string               `json:"hex,omitempty"`
}

Transaction represents a transaction

type TransactionDetails

type TransactionDetails struct {
	Account  string  `json:"account"`
	Address  string  `json:"address,omitempty"`
	Category string  `json:"category"`
	Amount   float64 `json:"amount"`
	Fee      float64 `json:"fee,omitempty"`
}

TransactionDetails represents details about a transaction

type TransactionOutSet

type TransactionOutSet struct {
	Height          uint32  `json:"height"`
	Bestblock       string  `json:"bestblock"`
	Transactions    float64 `json:"transactions"`
	TxOuts          float64 `json:"txouts"`
	BytesSerialized float64 `json:"bytes_serialized"`
	HashSerialized  string  `json:"hash_serialized"`
	TotalAmount     float64 `json:"total_amount"`
}

TransactionOutSet represents statistics about the unspent transaction output database

type UTransactionOut

type UTransactionOut struct {
	Bestblock     string       `json:"bestblock"`
	Confirmations uint32       `json:"confirmations"`
	Value         float64      `json:"value"`
	ScriptPubKey  ScriptPubKey `json:"scriptPubKey"`
	Version       uint32       `json:"version"`
	Coinbase      bool         `json:"coinbase"`
}

UTransactionOut represents a unspent transaction out (UTXO)

type UnspendableOutput

type UnspendableOutput struct {
	TxId string `json:"txid"`
	Vout uint64 `json:"vout"`
}

UnspendableOutput represents a unspendable (locked) output

type ValidateAddressResponse

type ValidateAddressResponse struct {
	IsValid      bool   `json:"isvalid"`
	Address      string `json:"address"`
	IsMine       bool   `json:"ismine"`
	IsScript     bool   `json:"isscript"`
	PubKey       string `json:"pubkey"`
	IsCompressed bool   `json:"iscompressed"`
	Account      string `json:"account"`
}

ValidateAddressResponse represents a response to "validateaddress" call

type Vin

type Vin struct {
	Coinbase  string    `json:"coinbase"`
	Txid      string    `json:"txid"`
	Vout      int       `json:"vout"`
	ScriptSig ScriptSig `json:"scriptSig"`
	Sequence  uint32    `json:"sequence"`
}

Vin represent an IN value

type Vout

type Vout struct {
	Value        float64      `json:"value"`
	N            int          `json:"n"`
	ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
}

Vout represent an OUT value

type Work

type Work struct {
	Midstate string `json:"midstate"`
	Data     string `json:"data"`
	Hash1    string `json:"hash1"`
	Target   string `json:"target"`
}

A Work represents a formatted hash data to work on

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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