1

This https://blog.iota.org/introducing-masked-authenticated-messaging-e55c1822d50e says that any channel can be splitting.

Also this https://medium.com/coinmonks/iota-mam-eloquently-explained-d7505863b413 says that you can fork channel.

I want to make it look like this channel: enter image description here

I have a question, how do I do this?

I tried to do this:

  1. I generate first root:
const Mam = require('mam.client.js');
const mamState = Mam.init(provider, 'seed');
mamState.channel.count = 1;
mamState.channel.next_count = 2;
mamState.channel.start = 0;
mamState.channel.index = 0;

const message = Mam.create(mamState, asciiToTrytes('hello'));
console.log(message);

I got ROOT: FXARNUTEKJOESHZEVKTKIMZIAMZXGATZHYZKZIZVC9WVKEZRBDOETXCFPOZIOTPECKSIIOKEJAQLBKZZS

and next_root: LJNTSVRRTKPVMYCIZQLI99CWQOJECA9WUYMOHPNXSWBAMOTHLSZGUYAMUKHAR9E9NWUNDCFBRHCYIUQFN

  1. Next, I'm trying to split the next message.
    mamState.channel.count = 2;
    mamState.channel.next_count = 1;
    mamState.channel.start = 1;
    mamState.channel.index = 0; // i try change index  to 0 or 1 but I don't get different roots
    
1
  • I think you should not manipulate any thing in state, in my idea it should be automatically when some one use new side_key. But I couldn't find any reference for that neither(at least in NodeJs)
    – masoud2011
    Commented Jan 10, 2020 at 15:59

1 Answer 1

0

Here body, I got it (I was considering the same thing, and find no codes of forking MAM channel on the Internet. Then i began my tries:-): Run these codes below for the first time:

const Mam = require('@iota/mam')
const { asciiToTrytes, trytesToAscii } = require('@iota/converter')

const mode = 'restricted'
const channelMode = 'restricted'
const sideKey = 'VERYSECRETKEY'
const provider = 'https://nodes.devnet.iota.org'//'https://xeevee.net:14267'

const mamExplorerLink = `https://mam-explorer.firebaseapp.com/?provider=${encodeURIComponent(provider)}&mode=${mode}&key=${sideKey.padEnd(81, '9')}&root=`

// Initialise MAM State
//let mamState = Mam.init(provider)
let mamState = Mam.init(provider,'Your Seed',2)
console.log('mamState: '+ JSON.stringify(mamState))
// Set channel mode
mamState = Mam.changeMode(mamState, mode, sideKey)

console.log('after changeMode mamState: '+ JSON.stringify(mamState))

// Publish to tangle
const publish = async packet => {
    // Create MAM Payload - STRING OF TRYTES
    // console.log('in publish before regular')
    // if (!/^[\x00-\x7F]*$/.test(JSON.stringify(packet)))
    // {
    //     console.log('Error(errors.INVALID_ASCII_CHARS)')
    // }
    const trytes = asciiToTrytes(JSON.stringify(packet))
    const message = await Mam.create(mamState, trytes)
    //console.log('MAM object: ',JSON.stringify(message))

    // Save new mamState
    //console.log('old mamState: '+ JSON.stringify(mamState))
    mamState =  message.state
    //console.log('new mamState: '+ JSON.stringify(mamState))
    //console.log('root before attach is',message.root)

    // Attach the payload
    await Mam.attach(message.payload, message.address, 3, 9)

    //console.log('Published', packet, '\n');
    //console.log('after:',message.root)
    return message.root
}




//console.time('test')
////timestamp: (new Date()).toLocaleString()
publish({
    message: 'XXX Mainchain'
})
    .then(async root => {

        //Output asyncronously using "logData" callback function

        await Mam.fetch(root, mode, sideKey)

        // //Output syncronously once fetch is completed
        const result = await Mam.fetch(root, mode, sideKey)
        //console.timeEnd('test')
        result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
        console.log('root is',root,'\n')
        console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);

    }).catch(e => {
    console.log(e) })



publish({
    message: 'maybe on the mainchain1'
})
    .then(async root => {

        const result = await Mam.fetch(root, mode, sideKey)
        result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
        console.log('root is',root,'\n')
        console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
        console.log('the first root is '+root)


    }).catch(e => {
    console.log(e)
    })


    publish({
        message: 'maybe on the mainchain2'
    }).then(async root => {
        const result = await Mam.fetch(root, mode, sideKey)
        result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
        console.log('root is',root,'\n')
        console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
        console.log('the first root is '+root)
    }).catch(e => {
        console.log(e)
    })

Then, run these codes for the second time(Do not change the seed):

const Mam = require('@iota/mam')
const { asciiToTrytes, trytesToAscii } = require('@iota/converter')

const mode = 'restricted'
const channelMode = 'restricted'
const sideKey = 'VERYSECRETKEY'
const provider = 'https://nodes.devnet.iota.org'//'https://xeevee.net:14267'

const mamExplorerLink = `https://mam-explorer.firebaseapp.com/?provider=${encodeURIComponent(provider)}&mode=${mode}&key=${sideKey.padEnd(81, '9')}&root=`

// Initialise MAM State
//let mamState = Mam.init(provider)
let mamState = Mam.init(provider,'Your Seed',2)
console.log('mamState: '+ JSON.stringify(mamState))
// Set channel mode
mamState = Mam.changeMode(mamState, mode, sideKey)

console.log('after changeMode mamState: '+ JSON.stringify(mamState))

// Publish to tangle
const publish = async packet => {
    // Create MAM Payload - STRING OF TRYTES
    // console.log('in publish before regular')
    // if (!/^[\x00-\x7F]*$/.test(JSON.stringify(packet)))
    // {
    //     console.log('Error(errors.INVALID_ASCII_CHARS)')
    // }
    const trytes = asciiToTrytes(JSON.stringify(packet))
    const message = await Mam.create(mamState, trytes)
    //console.log('MAM object: ',JSON.stringify(message))

    // Save new mamState
    //console.log('old mamState: '+ JSON.stringify(mamState))
    mamState =  message.state
    //console.log('new mamState: '+ JSON.stringify(mamState))
    //console.log('root before attach is',message.root)

    // Attach the payload
    await Mam.attach(message.payload, message.address, 3, 9)

    //console.log('Published', packet, '\n');
    //console.log('after:',message.root)
    return message.root
}




//console.time('test')
////timestamp: (new Date()).toLocaleString()
publish({
    message: 'XXX Mainchain'
})
    .then(async root => {

        //Output asyncronously using "logData" callback function

        await Mam.fetch(root, mode, sideKey)

        // //Output syncronously once fetch is completed
        const result = await Mam.fetch(root, mode, sideKey)
        //console.timeEnd('test')
        result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
        console.log('root is',root,'\n')
        console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);

    }).catch(e => {
    console.log(e) })



publish({
    message: 'maybe on the mainchain1'
})
    .then(async root => {

        const result = await Mam.fetch(root, mode, sideKey)
        result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
        console.log('root is',root,'\n')
        console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
        console.log('the first root is '+root)


    }).catch(e => {
    console.log(e)
    })


    publish({
        message: 'here we divert'
    }).then(async root => {
        const result = await Mam.fetch(root, mode, sideKey)
        result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
        console.log('root is',root,'\n')
        console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
        console.log('the first root is '+root)
    }).catch(e => {
        console.log(e)
    })

After all those above, we created two channels, the first is: {XXX Mainchain} -> {maybe on the mainchain1} -> {maybe on the mainchain2} the second is: {XXX Mainchain} -> {maybe on the mainchain1} -> {here we divert} And they have the same root! use the root in MAM explorer to find out what has happended(You have to query the MAM explorer for multiple times, then you will find that although the root is the same, the message chains are not!).

1
  • Remember to replace 'Your Seed' with your actual seed. And do remember that during the two rounds of executing the codes i posted, the seed must not change. Commented Oct 28, 2021 at 7:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.