Completed
Push — master ( 6b3d75...4e85f4 )
by thomas
29:00
created

AddressFactory   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 101
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 12

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 101
ccs 33
cts 33
cp 1
rs 10
c 0
b 0
f 0
wmc 13
lcom 0
cbo 12

6 Methods

Rating   Name   Duplication   Size   Complexity  
A fromString() 0 14 4
A fromKey() 0 4 1
A fromScript() 0 4 1
A fromOutputScript() 0 14 3
A isValidAddress() 0 11 2
A getAssociatedAddress() 0 10 2
1
<?php
2
3
namespace BitWasp\Bitcoin\Address;
4
5
use BitWasp\Bitcoin\Base58;
6
use BitWasp\Bitcoin\Bitcoin;
7
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\KeyInterface;
8
use BitWasp\Bitcoin\Key\PublicKeyFactory;
9
use BitWasp\Bitcoin\Network\NetworkInterface;
10
use BitWasp\Bitcoin\Script\Classifier\OutputClassifier;
11
use BitWasp\Bitcoin\Script\ScriptInterface;
12
use BitWasp\Bitcoin\Script\ScriptType;
13
use BitWasp\Buffertools\BufferInterface;
14
15
class AddressFactory
16
{
17
    /**
18
     * Returns a pay-to-pubkey-hash address for the given public key
19
     *
20
     * @param KeyInterface $key
21
     * @return PayToPubKeyHashAddress
22
     */
23 38
    public static function fromKey(KeyInterface $key)
24
    {
25 38
        return new PayToPubKeyHashAddress($key->getPubKeyHash());
26
    }
27
28
    /**
29
     * Takes the $p2shScript and generates the scriptHash address.
30
     *
31
     * @param ScriptInterface $p2shScript
32
     * @return ScriptHashAddress
33
     */
34 14
    public static function fromScript(ScriptInterface $p2shScript)
35
    {
36 14
        return new ScriptHashAddress($p2shScript->getScriptHash());
37
    }
38
39
    /**
40
     * @param ScriptInterface $outputScript
41
     * @return PayToPubKeyHashAddress|ScriptHashAddress
42
     */
43 8
    public static function fromOutputScript(ScriptInterface $outputScript)
44
    {
45 8
        $decode = (new OutputClassifier())->decode($outputScript);
46 8
        switch ($decode->getType()) {
47 8
            case ScriptType::P2PKH:
48
                /** @var BufferInterface $solution */
49 4
                return new PayToPubKeyHashAddress($decode->getSolution());
50 6
            case ScriptType::P2SH:
51
                /** @var BufferInterface $solution */
52 2
                return new ScriptHashAddress($decode->getSolution());
53
            default:
54 4
                throw new \RuntimeException('Script type is not associated with an address');
55
        }
56
    }
57
58
    /**
59
     * @param string $address
60
     * @param NetworkInterface $network
61
     * @return AddressInterface
62
     * @throws \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure
63
     */
64 42
    public static function fromString($address, NetworkInterface $network = null)
65
    {
66 42
        $network = $network ?: Bitcoin::getNetwork();
67 42
        $data = Base58::decodeCheck($address);
68 42
        $prefixByte = $data->slice(0, 1)->getHex();
69
70 42
        if ($prefixByte === $network->getP2shByte()) {
71 8
            return new ScriptHashAddress($data->slice(1));
72 34
        } else if ($prefixByte === $network->getAddressByte()) {
73 32
            return new PayToPubKeyHashAddress($data->slice(1));
74
        } else {
75 2
            throw new \InvalidArgumentException("Invalid prefix [{$prefixByte}]");
76
        }
77
    }
78
79
    /**
80
     * @param string $address
81
     * @param NetworkInterface $network
82
     * @return bool
83
     * @throws \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure
84
     */
85 26
    public static function isValidAddress($address, NetworkInterface $network = null)
86
    {
87
        try {
88 26
            self::fromString($address, $network);
89 24
            $is_valid = true;
90 2
        } catch (\Exception $e) {
91 2
            $is_valid = false;
92
        }
93
94 26
        return $is_valid;
95
    }
96
97
    /**
98
     * Following a loose definition of 'associated', returns
99
     * the current script types, and a PayToPubKeyHash address for P2PK.
100
     *
101
     * @param ScriptInterface $script
102
     * @return AddressInterface
103
     * @throws \RuntimeException
104
     */
105 4
    public static function getAssociatedAddress(ScriptInterface $script)
106
    {
107 4
        $classifier = new OutputClassifier();
108 4
        $decode = $classifier->decode($script);
109 4
        if ($decode->getType() === ScriptType::P2PK) {
110 2
            return PublicKeyFactory::fromHex($decode->getSolution())->getAddress();
111
        } else {
112 4
            return self::fromOutputScript($script);
113
        }
114
    }
115
}
116